Linguagem R para iniciantes: da programação básica à análise de dados

II Semana de Aperfeiçoamento em Engenharia Florestal (SEAFLOR)

Deivison Venicio Souza

Thiago Wendling Gonçalves de Oliveira

Luani Rosa de Oliveira Piva

16/julho/2018

1 O ambiente R

1.1 Um software estatístico livre

R é um ambiente de software livre de estatística e gráficos, capaz de compilar e executar em uma ampla variedade de plataformas UNIX, Windows e MacOS. Para fazer o download do R, é necessário escolher um espelho CRAN para que seja feito o download da versão mais atual. Os espelhos CRAN são servidores distribuídos em diversos países que armazenam o software R. Assim, ao deixar escolher de qual servidor será feito o download, permite-se que o usuário defina o servidor mais próximo de sua localização, reduzindo o tempo de tráfego.

2 Instalação do RGui e Rstudio

2.1 O RGui

2.1.1 Processo de download e instalação (p/ Windows)

1 PASSO: Acessar a página do projeto R em https://www.r-project.org/;

2 PASSO: Do lado esquerdo da página clique sobre o link CRAN;

3 PASSO: Será aberta uma página com diversos links de CRAN Mirrors, isto é, espelhos CRAN. O ideal é selecionar o servidor mais próximo da sua localização para fazer o download do R Development Core Team. Veja na tabela os principais espelhos disponíveis no Brasil.

\(\textbf{ Link }\) \(\textbf{ Instituição }\)
http://cran-r.c3sl.ufpr.br/ \(\color{blue}{\textbf{Universidade Federal do Paraná (UFPR)}}\)
http://nbcgib.uesc.br/mirrors/cran/ Center for Comp Biol at Universidade Estadual de Santa Cruz
https://cran.fiocruz.br/ Oswaldo Cruz Foundation, Rio de Janeiro
http://cran.fiocruz.br/ Oswaldo Cruz Foundation, Rio de Janeiro
https://vps.fmvz.usp.br/CRAN/ University of São Paulo, São Paulo
http://brieger.esalq.usp.br/CRAN/ University of São Paulo, Piracicaba

4 PASSO: Na página http://cran-r.c3sl.ufpr.br/, na seção Download and Install R, clicar em um dos três links, conforme o SO do usuário:

  1. Download R for Windows;
  2. Download R for Linux; ou
  3. Download R for (Mac) OS X.

5 PASSO: Clicar no link do subdiretório base ou em install R for the first time, para instalar o R pela primeira vez;

6 PASSO: Clicar em Download R (\(\color{blue}{escolher~versão}\)) for (\(\color{blue}{escolher~SO}\)). Assim, será iniciado o download do R Development Core Team para o respectivo sistema; e

7 PASSO: Por fim, basta usar o setup para instalar o programa.

2.2 O editor Rstudio

2.2.1 Processo de download e instalação (p/ Windows)

1 PASSO: Acessar a página do projeto RStudio: https://www.rstudio.com;

2 PASSO: Products \(\rightarrow\) RStudio;

3 PASSO: Selecionar a versão do RStudio para Desktop;

4 PASSO: Na edição Open source \(\rightarrow\) Download Rstudio Desktop;

5 PASSO: Installers for Supported Platforms \(\rightarrow\) instalador RStudio; e

6 PASSO: Por fim, basta usar o setup baixado para instalar o programa.

3 Iniciando no ambiente R

3.1 A janela inicial do RGui

No contato inicial do usuário com o RGui tem-se a visão inicial do R Console com a versão do R em uso e as condições de licenciamento. Algumas funções de teste são mostradas e, para saber o que cada função retorna basta digitá-las no prompt de comando do R Console simbolizado pelo sinal \(\color{red}{\textbf{>}}\) (maior) em vermelho. Haverá um cursor piscando à direita do prompt, indicando o local para digitar os comandos para o R.

Execute as funções \(\color{magenta}{\textbf{demo()}}\), \(\color{magenta}{\textbf{help()}}\), \(\color{magenta}{\textbf{help.start()}}\) e \(\color{magenta}{\textbf{q()}}\).

3.2 Operações e operadores aritméticos

A linguagem R permite executar operações aritméticas básica (soma, subtração, multiplicação, divisão e potenciação):

Operadores Nome Operações
\(\textbf{+}\) Somatório 2+3
\(\textbf{*}\) Multiplicação 4*9
\(\textbf{/}\) Divisão 20/5
\(\textbf{-}\) Subtração 32-10
\(\textbf{^ ou **}\) Potenciação 5^3
\(\textbf{%%}\) Resto inteiro da divisão 10%%3
\(\textbf{%/%}\) Parte inteira da divisão 10%/%3
2+3                             # Soma
## [1] 5
4*9                             # Multiplicação
## [1] 36
20/5                            # Divisão
## [1] 4
32-10                           # Subtração
## [1] 22
5^3                             # Potenciação
## [1] 125
10%%3                           # Resto inteiro da divisão
## [1] 1
10%/%3                          # Parte inteira da divisão 
## [1] 3

3.3 Operadores lógicos

\(\textbf{Operadores lógicos}\) \(\textbf{Descrição}\)
\(\textbf{<}\) Menor do que…
\(\textbf{>}\) Maior do que…
\(\textbf{<=}\) Menor ou igual do que…
\(\textbf{>=}\) Maior ou igual do que…
\(\textbf{==}\) Igual a…
\(\textbf{\&}\) E (and)/para vetores
\(\textbf{\&\&}\) E (and)
\(\textbf{|}\) Ou (or)/para vetores
\(\textbf{||}\) Ou (or)
\(\textbf{!=}\) Diferente de…
\(\textbf{!}\) Não…
\(\textbf{is.na()}\) Valor numérico ou faltante…

3.4 Alguns comandos básicos

\(\textbf{Comando}\) \(\textbf{Ação}\)
\(\color{magenta}{\textbf{ls()}}\) ou \(\color{magenta}{\textbf{objects()}}\) Listar os objetos na janela de trabalho atual
\(\color{magenta}{\textbf{rm()}}\) Remover um objeto qualquer
\(\color{magenta}{\textbf{help()}}\) Solicitar ajuda sobre o uso de uma função
\(\color{magenta}{\textbf{Ctrl + L}}\) Limpar a tela do R console
\(\color{magenta}{\textbf{history()}}\) Listar os últimos comandos executados
\(\color{magenta}{\textbf{getwd()}}\) Mostrar o diretório de trabalho
\(\color{magenta}{\textbf{setwd()}}\) Mudar o diretório de trabalho
\(\color{magenta}{\textbf{install.packages()}}\) Instalar um pacote específico
\(\color{magenta}{\textbf{q()}}\) Fechar o console R
\(\color{magenta}{\textbf{library()}}\) Carregar um pacote específico
\(\color{magenta}{\textbf{dir()}}\) Listar os arquivos existentes no diretório
\(\color{magenta}{\textbf{getOption("OutDec")}}\) Verificar o separador decimal definido
\(\color{magenta}{\textbf{options(OutDec=",")}}\) Mudar o separador decimal para vírgula
\(\color{magenta}{\textbf{round(x, digits=0)}}\) Função para arredondamento de casas decimais
\(\color{magenta}{\textbf{data()}}\) Lista os conjuntos de dados dos pacotes atualmente carregados
\(\color{magenta}{\textbf{?nome_do_dataset}}\) Obter informações detalhadas sobre um data set
\(\color{magenta}{\textbf{class()}}\) Verificar a classe de um objeto específico
\(\color{magenta}{\textbf{search()}}\) Listar todos os pacotes carregados

4 Estrutura de dados no R

4.1 Tipos de objetos no R

Os objetos são criados no R com o objetivo de \(\textbf{armazenar dados}\). Todo objeto em R têm uma classe, que pode ser descoberta usando a função \(\color{magenta}{\textbf{class()}}\). Os objetos-vetores podem ser do tipo numeric, logical, character, etc. Outros objetos incluem matrizes, data frames, funções, listas, arrays.

Antes de iniciar as seções que detalham os tipos de objetos existentes no R é importante saber como nomeá-los. Assim, podemos listar algumas condições para atribuição de nomes à objetos:

  1. O nome do objeto deve, necessariamente, iniciar com uma letra;
  2. Pode-se usar letras maiúsculas ou minúsculas no nome do objeto;
  3. O nome dos objetos são sensíveis às letras maiúsculas ou minúsculas (ex: Ufpr / ufpr);
  4. O nome não pode ter símbolos de funções ou operações matemáticas (+; /; -; *; ^);
  5. Números (0 a 9) podem ser inseridos no nome do objeto, exceto na primeira posição;
  6. Não se pode usar espaço entre os nomes dos objetos (alternativa = usar ponto (\(\textbf{.}\)) ou underline (\(\textbf{_}\));
  7. Para atribuir o nome a um objeto deve-se usar o comando (recebe); e
  8. Pode-se usar também a função para fazer atribuição (menos comum).

Obs.: O R é \(\color{red}{\textbf{case sensitive}}\), isto é, diferencia letras maiúsculas e minúsculas.

4.1.1 Vetores

O vetor é o tipo de objeto mais importante em R, constituindo a forma mais simples de armazenar dados. São caracterizados por possuírem somente uma dimensão e, todos os elementos constituintes devem ter, obrigatoriamente, a mesma natureza (classe).

Os vetores podem ser considerados como células contíguas que contém dados. Estas células podem ser acessadas por meio de operações de indexação (R Language Definition).

As principais classes de vetores são:

  1. numeric;
  2. character;
  3. integer;
  4. logical;
  5. complex; e
  6. factor.

4.1.1.1 Quais funções usar para criar um vetor?

a) Função \(\color{magenta}{\textbf{c()}}\) (concatenate): Função genérica que permite concatenar (combinar) argumentos para formar um vetor.

b) Função \(\color{magenta}{\textbf{seq()}}\) (sequence): Função genérica usada para gerar sequências de números em intervalos pré-definidos. Os principais parâmetros da função \(\color{magenta}{\textbf{seq()}}\):

\(\textbf{Sintaxe}\)

\(\color{black}{\textbf{seq(from = ?, to = ?, by= ?, length.out = ?, along.with = ?)}}\)

Onde:

\(\color{magenta}{\textbf{from}}\) = define um valor inicial (start) para a sequência;

\(\color{magenta}{\textbf{to}}\) = define um valor máximo para a sequência;

\(\color{magenta}{\textbf{by}}\) = define um valor incremental para a sequência;

\(\color{magenta}{\textbf{length.out}}\) = define o comprimento da sequência dentro de um intervalo; e

\(\color{magenta}{\textbf{along.with}}\) = define uma sequência de inteiros do tamanho do argumento repassado.

c) Função \(\color{magenta}{\textbf{rep()}}\) (replicate): Função genérica usada para replicar um valor “x” . Os principais parâmetros da função \(\color{magenta}{\textbf{rep()}}\):

\(\textbf{Sintaxe}\)

\(\color{black}{\textbf{rep(x = ?, times = ?, each = ?)}}\)

Onde:

\(\color{magenta}{\textbf{x}}\) = escalar, vetor (incluindo uma lista), entre outros;

\(\color{magenta}{\textbf{times}}\) = Um vetor inteiro (não negativo) indicando quantas vezes repetir cada elemento; e

\(\color{magenta}{\textbf{each}}\) = Cada elemento de x é repetido n vezes.

d) Função \(\color{magenta}{\textbf{scan()}}\): Usada para criar vetores diretamente no R Console.

Existe uma sutil diferença ao utilizar a função \(\color{magenta}{\textbf{c()}}\) para criar vetores de números ou de caracteres.

  • Vetor numérico: Deve-se concatenar os números separando-os por vírgula; e

  • Vetor de caractere: Deve-se escrever cada elemento entre aspas e separá-los por vírgula.

a) Função \(\color{magenta}{\textbf{c()}}\) (concatenate):

# Criando objeto-vetor e atribuindo nomes.

c("Acapu", "Araucaria", "Mogno", "Cedro", "Ipe")
assign("especie", c("Acapu", "Araucaria", "Mogno", "Cedro", "Ipe"))
especie <- c("Acapu", "Araucaria", "Mogno", "Cedro", "Ipe")     

c(23.0, 27.0, 33.6, 42.6, 52.1)
diametro <- c(23.0, 27.0, 33.6, 42.6, 52.1)

c(8.5, 9.2, 10.5, 13.4, 15.8)
altura <- c(8.5, 9.2, 10.5, 13.4, 15.8)

Obs.: A Função \(\color{magenta}{\textbf{assign()}}\) também pode ser usada para concatenar.

\(\textbf{Elementos de diferentes naturezas no mesmo vetor?}\)

Você já sabe que um vetor é constituído por elementos de uma mesma classe (natureza). Então, o que aconteceria caso tentássemos criar um vetor com elementos de diferentes naturezas? Neste caso, o R fará com que todos os elementos do vetor tenham o mesma natureza.

Considere a criação de um vetor com dois tipos de elementos: numérico e caractere

x <- c(42.6, 23.0, 27.0, 33.6, "Acapu")
print(x)
## [1] "42.6"  "23"    "27"    "33.6"  "Acapu"
class(x)
## [1] "character"

Perceba que na existência de um elemento do tipo caractere (strings) todos os elementos númericos foram transformados para caractere (elementos ficaram entre aspas!). Assim, a classe do vetor é coagida a character. Isto siginifica, por exemplo, que o primeiro elemento do vetor “x” é a string “42.6” e não um número 42.6. Em consequência, operações matemáticas não poderiam ser aplicadas sobre este vetor.

b) Função \(\color{magenta}{\textbf{seq()}}\) (sequence):

\(\color{black}{\textbf{seq(from = ?, to = ?, by = ?, length.out = ?, along.with = ?)}}\)

especie <- c("Acapu", "Araucaria", "Mogno", "Cedro", "Ipe")

seq(10)                             # Sequência de 1 a 10, com intervalo 1.
##  [1]  1  2  3  4  5  6  7  8  9 10

seq(1:10)                           # Sequência de 1 a 10, com intervalo 1.
##  [1]  1  2  3  4  5  6  7  8  9 10

seq(from = 1, to = 10, by = 1)      # Sequência de 1 a 10, com intervalo 1.
##  [1]  1  2  3  4  5  6  7  8  9 10

seq(from = -2, to = 10, by = 2)     # Sequência de -2 a 10, com intervalo 2.
## [1] -2  0  2  4  6  8 10

seq(from=0, to=1, length.out = 11)  # Sequência de 11 números entre 0 e 1.
##  [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

seq(along.with = especie)           # Sequência do tamanho do vetor-espécie.
## [1] 1 2 3 4 5

c) Função \(\color{magenta}{\textbf{rep()}}\) (replicate):

\(\color{black}{\textbf{rep(x = ?, times = ?, each = ?)}}\)

rep(x = 1:4, 2)                  # Repete a sequência de 1 a 4 (2x).
## [1] 1 2 3 4 1 2 3 4

rep(1:4, times = 3)              # Repe a sequência de 1 a 4 (3x).
##  [1] 1 2 3 4 1 2 3 4 1 2 3 4

rep(x = 1:4, each = 2)           # Repete cada valor em "x" (2x).
## [1] 1 1 2 2 3 3 4 4

rep(1:4, c(2,2,2,2))             # Repete cada valor em "x" (2x).
## [1] 1 1 2 2 3 3 4 4

rep(1:4, c(2,1,2,1))             # Repete cada valor em "x", com base em c().
## [1] 1 1 2 3 3 4

rep(1:4, each = 2, len = 4)      # Repete cada valor em "x", até 4 números.
## [1] 1 1 2 2

rep(1:4, each = 2, len = 10)     # Regra da reciclagem.
##  [1] 1 1 2 2 3 3 4 4 1 1

rep(1:4, each = 2, times = 3)    # Repete cada valor em "x" (2x), por 3x.
##  [1] 1 1 2 2 3 3 4 4 1 1 2 2 3 3 4 4 1 1 2 2 3 3 4 4

d) Função \(\color{magenta}{\textbf{scan()}}\)

Crie os vetores abaixo usando a função \(\color{magenta}{\textbf{scan()}}\):

especie <- c("Acapu", "Araucaria", "Mogno", "Cedro", "Ipe")

diametro <- c(23.0, 27.0, 33.6, 42.6, 52.1)

altura <- c(8.5, 9.2, 10.5, 13.4, 15.8)

4.1.1.2 Como identificar a classe de um objeto-vetor no R?

A identificação da classe de um objeto-vetor no R pode ser feita usando a função \(\color{magenta}{\textbf{class()}}\). Além disso, existem funções lógicas que testam a classe de um objeto-vetor:

\(\color{magenta}{\textbf{is.numeric()}}\);

\(\color{magenta}{\textbf{is.character()}}\);

\(\color{magenta}{\textbf{is.factor()}}\);

\(\color{magenta}{\textbf{is.integer()}}\); e

\(\color{magenta}{\textbf{is.logical()}}\).

a) Objeto-vetor da classe “numeric”

a <- 45; class(a); is.numeric(a)
## [1] "numeric"
## [1] TRUE

b <- pi; class(b); is.numeric(b)
## [1] "numeric"
## [1] TRUE

c <- sqrt(2); class(c); is.numeric(c)
## [1] "numeric"
## [1] TRUE

diametro <- c(23.0, 27.0, 33.6, 42.6, 52.1)

class(diametro); is.numeric(diametro)
## [1] "numeric"
## [1] TRUE

b) Objeto-vetor da classe “character”

d <- "olá Mundo"; class(d); is.character(d)
## [1] "character"
## [1] TRUE

e <- c("Quem vai ao Pará", "Parou", "tomou açai, ficou!")
class(e); is.character(e)
## [1] "character"
## [1] TRUE

especie <- c("Acapu", "Araucaria", "Mogno", "Cedro", "Ipe")
class(especie); is.character(especie)
## [1] "character"
## [1] TRUE

c) Objeto-vetor da classe “factor”

A função \(\color{magenta}{\textbf{factor()}}\) é usada para codificar um vetor como um “fator” (categorias). Outra alternativa é usar a função de conversão \(\color{magenta}{\textbf{as.factor()}}\).

Um dos usos mais importantes dos fatores está na modelagem estatística. As variáveis categóricas entram em modelos estatísticos de maneira diferente das variáveis contínuas. Assim, o armazenamento de dados como fatores garante que as funções de modelagem tratem esses dados corretamente.

Os fatores em R são armazenados como um vetor de valores inteiros com um conjunto correspondente de valores de caractere a serem usados quando o fator é exibido. Os níveis (levels) de um fator sempre serão valores de caracteres.

No exemplo a seguir, observe que o objeto-vetor cortar ao ser impresso no console do R pertence à classe character, e todos os seus valores são mostrados entre “aspas”. Iremos usar a função \(\color{magenta}{\textbf{factor()}}\) para transformar o objeto-vetor para a classe factor. Feito isso, você perceberá que os elementos não serão impressos entre “aspas” e, ainda, que foram transformados em níveis de fator, no caso Não e Sim.

cortar <- c("Não", "Não", "Não", "Não", "Sim", "Sim")
print(cortar); class(cortar)
## [1] "Não" "Não" "Não" "Não" "Sim" "Sim"
## [1] "character"

fcortar <- factor(cortar)
print(fcortar)
## [1] Não Não Não Não Sim Sim
## Levels: Não Sim

Os rótulos (nomes) dos níveis de fatores podem ser alterados através do argumento labels:

fuste <- c(1, 2, 2, 3, 1, 2, 3, 3, 1, 2, 3, 3, 1, 4, 4)
print (fuste); class(fuste)
##  [1] 1 2 2 3 1 2 3 3 1 2 3 3 1 4 4
## [1] "numeric"

ffuste <- factor(x = fuste, 
                 labels = c("I","II","III", "IV"))
print(ffuste)
##  [1] I   II  II  III I   II  III III I   II  III III I   IV  IV 
## Levels: I II III IV

levels(ffuste)
## [1] "I"   "II"  "III" "IV"

Por default os fatores (levels) ficam dispostos em ordem alfabética:

# Fatores (levels) em ordem alfabética!

mes <- c ("Março", "Abril", "Janeiro", "Novembro", 
          "Agosto","Setembro", "Outubro", "Julho", 
          "Dezembro", "Fevereiro", "Maio", "Junho")
class(mes)
## [1] "character"

fmes <- factor(mes)
class(fmes)
## [1] "factor"

print(fmes)
##  [1] Março     Abril     Janeiro   Novembro  Agosto    Setembro  Outubro  
##  [8] Julho     Dezembro  Fevereiro Maio      Junho    
## 12 Levels: Abril Agosto Dezembro Fevereiro Janeiro Julho Junho ... Setembro

Pode-se declarar explicitamente que existe uma hierarquia entre os fatores usando ordered = TRUE.

# Fatores ordenados
fmes2 <- factor(x = mes, 
         levels = c("Janeiro", "Fevereiro", "Março", "Abril", 
                     "Maio", "Junho", "Julho", "Agosto", 
                     "Setembro", "Outubro", "Novembro", "Dezembro"),
              ordered = TRUE);
class(fmes2)
## [1] "ordered" "factor"
print(fmes2)
##  [1] Março     Abril     Janeiro   Novembro  Agosto    Setembro  Outubro  
##  [8] Julho     Dezembro  Fevereiro Maio      Junho    
## 12 Levels: Janeiro < Fevereiro < Março < Abril < Maio < ... < Dezembro

4.1.1.3 Elementos especias

Todo objeto-vetor pode possuir elementos especiais: NA (Not Available). Esta string dentro de um objeto-vetor significa um valor desconhecido. Por exemplo, imagine que você realizou uma prova em uma turma de 10 alunos, porém 2 faltaram. Poderíamos específicar um vetor de notas sem desconsiderar a existência dos alunos que faltaram:

# Not Available
notas <- c(5.6, 6.7, NA, 8.9, 2.3, 5.6, 7.8, 8.9, 6.1, NA)
print(notas)
##  [1] 5.6 6.7  NA 8.9 2.3 5.6 7.8 8.9 6.1  NA
length(notas)
## [1] 10
is.na(notas)
##  [1] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE

4.1.2 Matrizes

4.1.2.1 Como criar matrizes?

As matrizes diferenciam-se dos vetores por admitirem duas dimensões, expressas por linhas e colunas. Uma matriz pode ser formada por elementos numéricos e/ou caracteres (strings) na sua estrutura.

A construção de matrizes no R pode ser feita com uso das funções \(\color{magenta}{\textbf{rbind()}}\) (row bind) e \(\color{magenta}{\textbf{cbind()}}\) (colum bind). No entanto, o mecanismo mais eficiente para construir matrizes é usar a função \(\color{magenta}{\textbf{matrix()}}\).

As funções \(\color{magenta}{\textbf{rbind()}}\) e \(\color{magenta}{\textbf{cbind()}}\) organizam objetos-vetores em linhas ou colunas, respectivamente.

Quando utilizadas as funções \(\color{magenta}{\textbf{rbind()}}\) e \(\color{magenta}{\textbf{cbind()}}\) para construir matrizes a partir de vetores de diferentes classes (ex.: mat.2 e mat.4), todos os dados numéricos da matriz são convertidos em caracteres, fato evidenciado pelos números entre aspas na saída.

a) Função \(\color{magenta}{\textbf{rbind()}}\)

especie <- c("Acapu", "Araucaria", "Mogno", "Cedro", "Ipe")
diametro <- c(23.0, 27.0, 33.6, 42.6, 52.1)
altura <- c(8.4, 8.7, 9.1, 13.2, 15.4)

mat.1<-rbind(diametro, altura)
print(mat.1)
##          [,1] [,2] [,3] [,4] [,5]
## diametro 23.0 27.0 33.6 42.6 52.1
## altura    8.4  8.7  9.1 13.2 15.4

mat.2<-rbind(especie, diametro)
print(mat.2)
##          [,1]    [,2]        [,3]    [,4]    [,5]  
## especie  "Acapu" "Araucaria" "Mogno" "Cedro" "Ipe" 
## diametro "23"    "27"        "33.6"  "42.6"  "52.1"

b) Função \(\color{magenta}{\textbf{cbind()}}\)

mat.3 <- cbind(diametro, altura)
print(mat.3)
##      diametro altura
## [1,]     23.0    8.4
## [2,]     27.0    8.7
## [3,]     33.6    9.1
## [4,]     42.6   13.2
## [5,]     52.1   15.4

mat.4 <- cbind(especie, diametro, altura)
print(mat.4)
##      especie     diametro altura
## [1,] "Acapu"     "23"     "8.4" 
## [2,] "Araucaria" "27"     "8.7" 
## [3,] "Mogno"     "33.6"   "9.1" 
## [4,] "Cedro"     "42.6"   "13.2"
## [5,] "Ipe"       "52.1"   "15.4"

c) Função \(\color{magenta}{\textbf{matrix()}}\)

A maneira mais prática para criar matrizes no R é usar a função \(\color{magenta}{\textbf{matrix()}}\).

\(\color{black}{\textbf{matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL)}}\)

Onde:

\(\color{magenta}{\textbf{data}}\) = Um vetor de dados opcional;

\(\color{magenta}{\textbf{nrow}}\) = Número desejado de linhas;

\(\color{magenta}{\textbf{ncol}}\) = Número desejado de colunas;

\(\color{magenta}{\textbf{byrow}}\) = Argumento lógico. Se FALSE = default (a matriz é preenchida por colunas). Se TRUE (matriz é preenchida por linhas); e

\(\color{magenta}{\textbf{dimnames}}\) = Insere os rótulos das linhas e colunas da matriz com a função \(\color{magenta}{\textbf{list()}}\).

Para facilitar a identificação pode-se atribuir rótulos às linhas e colunas da matriz. Para tanto, pode-se usar as funções \(\color{magenta}{\textbf{rownames()}}\) e \(\color{magenta}{\textbf{colnames()}}\) ou o argumento dimnames em \(\color{magenta}{\textbf{matrix()}}\).

# Cria uma matriz de 1 a 6, com 2 linhas e 3 colunas
mat.5 <- matrix(1:6, nrow=2, ncol=3) 
print(mat.5)
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6

# Atribui nomes às linhas e colunas da “mat.5”
rownames(mat.5) <- c("L1","L2") 
print(mat.5)
##    [,1] [,2] [,3]
## L1    1    3    5
## L2    2    4    6

colnames(mat.5) <- c("C1","C2","C3")
print(mat.5)
##    C1 C2 C3
## L1  1  3  5
## L2  2  4  6

Pode-se usar objetos-vetores já existente na função \(\color{magenta}{\textbf{matrix()}}\):

# Criar uma matriz a partir de objetos-vetores existente
especie <- c("Acapu", "Araucaria", "Mogno", "Cedro", "Ipe")
diametro <- c(23.0, 27.0, 33.6, 42.6, 52.1)

mat.6 <- matrix(diametro, nrow=5, ncol=1, byrow = TRUE,
              dimnames = list(especie)); print(mat.6)
##           [,1]
## Acapu     23.0
## Araucaria 27.0
## Mogno     33.6
## Cedro     42.6
## Ipe       52.1

Atribuindo nome a única coluna da matriz 6 usando \(\color{magenta}{\textbf{colnames()}}\):

colnames(mat.6) <- "diâmetro"

print(mat.6)
##           diâmetro
## Acapu         23.0
## Araucaria     27.0
## Mogno         33.6
## Cedro         42.6
## Ipe           52.1

Atribuindo nomes às linhas e colunas com o argumento dimnames de \(\color{magenta}{\textbf{matrix()}}\):

mat.7<-matrix(1:6, nrow=2, ncol=3, byrow = TRUE, 
              dimnames = list(c("L1", "L2"), 
                              c("C1", "C2", "C3")))
print(mat.7)
##    C1 C2 C3
## L1  1  2  3
## L2  4  5  6

4.1.2.2 Situações especiais

Na criação de matrizes é interessante atentar-se para algumas situações especiais:

a) Descarte de elementos: Quando a quantidade de elementos em for > (ncol x nrow); e

b) Regra da Reciclagem: Quando ncol x nrow for > do que a quantidade de elementos.

# Número de elementos > ncol x nrow (Descarte)
mat.8 <- matrix(1:9, nrow=2, ncol=3, byrow = TRUE, 
              dimnames = list(c("L1", "L2"), 
                              c("C1", "C2", "C3")))
## Warning in matrix(1:9, nrow = 2, ncol = 3, byrow = TRUE, dimnames =
## list(c("L1", : comprimento dos dados [9] não é um submúltiplo ou múltiplo
## do número de linhas [2]
print(mat.8)
##    C1 C2 C3
## L1  1  2  3
## L2  4  5  6

# ncol x nrow > número de elementos (Reciclagem)
mat.9 <- matrix(1:6, nrow=3, ncol=3, byrow = TRUE, 
              dimnames = list(c("L1", "L2", "L3"), 
                              c("C1", "C2", "C3")))
print(mat.9)
##    C1 C2 C3
## L1  1  2  3
## L2  4  5  6
## L3  1  2  3

4.1.3 Data frames

O data frame é bastante similar a matriz, porém é capaz de reunir vetores de diferentes classes (naturezas) com a condição de possuírem igual comprimento.

Para criar data frames diretamente no R pode-se usar das funções \(\color{magenta}{\textbf{data.frame()}}\) ou \(\color{magenta}{\textbf{edit()}}\). Em geral, quando importa-se dados para o R, oriundos de um arquivo .CSV ou .txt pelos comandos \(\color{magenta}{\textbf{read.csv()}}\) e \(\color{magenta}{\textbf{read.table()}}\), respectivamente, o R armazena-os no formato de um data frame.

Após, criar o data frame é interessante avaliar a sua estrutura através das funções \(\color{magenta}{\textbf{str()}}\) e \(\color{magenta}{\textbf{dim()}}\). A funcão \(\color{magenta}{\textbf{str()}}\) retorna as colunas com suas respectivas classes e número de observações por variável.

Ainda, deve-se notar que a função \(\color{magenta}{\textbf{data.frame()}}\) transforma por default as variáveis qualitativas em fatores (classe factor) com a especificação da quantidade de níveis (levels). Isso ocorre devido a argumentação \(\color{blue}{\textbf{stringsAsFactors}}\) da funcão \(\color{magenta}{\textbf{data.frame()}}\) que possui como default transformar qualquer variável qualitativa em fator. Caso a transformação não seja desejável basta usar o comando \(\color{blue}{\textbf{stringsAsFactors}}\) = FALSE. Assim, as variáveis qualitativas serão mantidas no formato character.

a) Função \(\color{magenta}{\textbf{data.frame()}}\)

# Criar data frame a partir de vetores existentes
especie <- c("Acapu", "Araucaria", "Mogno", "Cedro", "Ipe")
diametro <- c(23.0, 27.0, 33.6, 42.6, 52.1)
altura <- c(8.4, 8.7, 9.1, 13.2, 15.4)
cortar <- c("Não", "Não", "Não", "Não", "Sim")

invFlor.1 <- data.frame(especie, diametro, altura, cortar,
                        stringsAsFactors = TRUE)
print(invFlor.1)
##     especie diametro altura cortar
## 1     Acapu     23.0    8.4    Não
## 2 Araucaria     27.0    8.7    Não
## 3     Mogno     33.6    9.1    Não
## 4     Cedro     42.6   13.2    Não
## 5       Ipe     52.1   15.4    Sim

# Observe a ação de stringsAsFactors = TRUE: factor.
str(invFlor.1)
## 'data.frame':    5 obs. of  4 variables:
##  $ especie : Factor w/ 5 levels "Acapu","Araucaria",..: 1 2 5 3 4
##  $ diametro: num  23 27 33.6 42.6 52.1
##  $ altura  : num  8.4 8.7 9.1 13.2 15.4
##  $ cortar  : Factor w/ 2 levels "Não","Sim": 1 1 1 1 2

dim(invFlor.1)
## [1] 5 4
# Cria data frame com apenas um comando
invFlor.2 <- data.frame(
  Especie = c("Acapu", "Araucaria", "Mogno", "Cedro", "Ipe"), 
  diametro = c(23.0, 27.0, 33.6, 42.6, 52.1),
  altura = c(8.4, 8.7, 9.1, 13.2, 15.4),
  cortar = c("Não", "Não", "Não", "Não", "Sim"),
  stringsAsFactors = FALSE)

print(invFlor.2)
##     Especie diametro altura cortar
## 1     Acapu     23.0    8.4    Não
## 2 Araucaria     27.0    8.7    Não
## 3     Mogno     33.6    9.1    Não
## 4     Cedro     42.6   13.2    Não
## 5       Ipe     52.1   15.4    Sim

# Observe a ação de stringsAsFactors = FALSE: character.
str(invFlor.2)
## 'data.frame':    5 obs. of  4 variables:
##  $ Especie : chr  "Acapu" "Araucaria" "Mogno" "Cedro" ...
##  $ diametro: num  23 27 33.6 42.6 52.1
##  $ altura  : num  8.4 8.7 9.1 13.2 15.4
##  $ cortar  : chr  "Não" "Não" "Não" "Não" ...

dim(invFlor.2)
## [1] 5 4

b) Função \(\color{magenta}{\textbf{edit()}}\)

A função \(\color{magenta}{\textbf{edit()}}\) pode ser usada para editar data frames já existentes, ou ainda, para iniciar uma tabulação de dados diretamente no R. Assim, ao executar o comando \(\color{magenta}{\textbf{edit(data.frame())}}\) será aberto um R Data Editor “vazio” permitindo a organização e tabulação de dados de modo similar ao Microsoft Excel.

No entanto, se o data frame já existe, você terá a opção de editá-lo através do comando \(\color{magenta}{\textbf{edit(nome do df)}}\), de tal modo que o data.frame será aberto no R Data Editor, admitindo a alteração ou correção de quaisquer informações que desejar.

# Crie um data frame com o comando edit() e atribua a "invFlor.3"
invFlor.3 <- edit(data.frame())

# Edite as informações do data frame “invFlor.2” e atribua a "invFlor.4"
invFlor.4 <- edit(invFlor.2)

4.1.4 Listas

Uma lista é um objeto que constituí uma coleção ordenada de objetos conhecidos. Um aspecto importante da lista é que admite diferentes estruturas (vetores, matrizes, data frames e, inclusive outras listas). A função \(\color{magenta}{\textbf{list()}}\) é usada para criar uma lista. Se os objetos já existem pode-se simplesmente adicioná-los à função \(\color{magenta}{\textbf{list()}}\).

Diferentemente de data frames as listas admitem vetores de comprimentos distintos. O número de componentes de uma lista (nível superior) pode ser obtido usando a função \(\color{magenta}{\textbf{length(nome do objeto)}}\).

Os componentes de uma lista podem ser nomeados. Fazendo-se isso, o acesso aos seus componentes (nível superior) pode ser feito com uso de \(\color{red}{\$}\) (dólar) ao invés de \(\color{red}{[[~~]]}\) (colchetes duplos). Nomear os níveis superior da lista é bastante útil, pois facilita a identificação do componente a ser acessado por indexação. (estudaremos indexação de objetos mais adiante!)

Função \(\color{magenta}{\textbf{list()}}\)

Pode-se criar uma lista a partir de objetos já existentes. A seguir um exemplo de lista cujos componentes são objetos-vetores:

# Cria objetos-vetores
especie <- c("Acapu", "Araucaria", "Mogno", "Cedro", "Ipe")
diametro <- c(23.0, 27.0, 33.6, 42.6, 52.1)
altura <- c(8.4, 8.7, 9.1, 13.2, 15.4)

# lista sem atribuir nomes aos os objetos
list.1 <- list(especie, diametro, altura)
print(list.1)
## [[1]]
## [1] "Acapu"     "Araucaria" "Mogno"     "Cedro"     "Ipe"      
## 
## [[2]]
## [1] 23.0 27.0 33.6 42.6 52.1
## 
## [[3]]
## [1]  8.4  8.7  9.1 13.2 15.4

length(list.1)
## [1] 3

Pode-se criar uma lista com diferentes classes de objetos. A seguir uma lista com três componentes: um vetor, uma matriz e um data frame:

#---------------------------------------------------------------------
# Uma lista com diferentes classes de objetos
list.2 <- list(diametro, mat.7, invFlor.1)
print(list.2)
## [[1]]
## [1] 23.0 27.0 33.6 42.6 52.1
## 
## [[2]]
##    C1 C2 C3
## L1  1  2  3
## L2  4  5  6
## 
## [[3]]
##     especie diametro altura cortar
## 1     Acapu     23.0    8.4    Não
## 2 Araucaria     27.0    8.7    Não
## 3     Mogno     33.6    9.1    Não
## 4     Cedro     42.6   13.2    Não
## 5       Ipe     52.1   15.4    Sim

length(list.2)
## [1] 3

str(list.2)
## List of 3
##  $ : num [1:5] 23 27 33.6 42.6 52.1
##  $ : int [1:2, 1:3] 1 4 2 5 3 6
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : chr [1:2] "L1" "L2"
##   .. ..$ : chr [1:3] "C1" "C2" "C3"
##  $ :'data.frame':    5 obs. of  4 variables:
##   ..$ especie : Factor w/ 5 levels "Acapu","Araucaria",..: 1 2 5 3 4
##   ..$ diametro: num [1:5] 23 27 33.6 42.6 52.1
##   ..$ altura  : num [1:5] 8.4 8.7 9.1 13.2 15.4
##   ..$ cortar  : Factor w/ 2 levels "Não","Sim": 1 1 1 1 2

Os componentes de uma lista podem ser nomeados. Fazendo isso, a identificação e a indexação dos componentes é facilitada.

#---------------------------------------------------------------------
# Uma lista de objetos-vetores (nomeados)
list.2 <- list(vetor = diametro, matriz = mat.7, DF = invFlor.1)
print(list.2)
## $vetor
## [1] 23.0 27.0 33.6 42.6 52.1
## 
## $matriz
##    C1 C2 C3
## L1  1  2  3
## L2  4  5  6
## 
## $DF
##     especie diametro altura cortar
## 1     Acapu     23.0    8.4    Não
## 2 Araucaria     27.0    8.7    Não
## 3     Mogno     33.6    9.1    Não
## 4     Cedro     42.6   13.2    Não
## 5       Ipe     52.1   15.4    Sim

length(list.2)
## [1] 3

list.3 <- list(Especie = especie, Diametro = diametro, Altura = altura)
print(list.3)
## $Especie
## [1] "Acapu"     "Araucaria" "Mogno"     "Cedro"     "Ipe"      
## 
## $Diametro
## [1] 23.0 27.0 33.6 42.6 52.1
## 
## $Altura
## [1]  8.4  8.7  9.1 13.2 15.4

length(list.3)
## [1] 3

Concatenando listas

Quando a intenção é unir diferentes listas em um único objeto pode-se usar a função \(\color{magenta}{\textbf{c()}}\). O novo objeto criado será também uma lista, cujos componentes serão os mesmos dos objetos-listas concatenados e, dispostos na ordem dos argumentos repassados.

list.4 <- list(Especie = especie, Diametro = diametro)
list.5 <- list(Altura = altura, Cortar = cortar)
list.6 <- c(list.4, list.5)

print(list.6)
## $Especie
## [1] "Acapu"     "Araucaria" "Mogno"     "Cedro"     "Ipe"      
## 
## $Diametro
## [1] 23.0 27.0 33.6 42.6 52.1
## 
## $Altura
## [1]  8.4  8.7  9.1 13.2 15.4
## 
## $Cortar
## [1] "Não" "Não" "Não" "Não" "Sim"

Lista \(\rightarrow\) Data frame: Usar a função \(\color{magenta}{\textbf{as.data.frame()}}\)

Um objeto-lista pode ser coagido (transformado) em um data frame usando a função , desde que as restrições de criação de data frames sejam satisfeitas. Isto é, a lista a ser coagida deve possuir vetores de igual comprimento.

as.data.frame(list.6)
##     Especie Diametro Altura Cortar
## 1     Acapu     23.0    8.4    Não
## 2 Araucaria     27.0    8.7    Não
## 3     Mogno     33.6    9.1    Não
## 4     Cedro     42.6   13.2    Não
## 5       Ipe     52.1   15.4    Sim

5 Indexação no R

5.1 Mecanismos de indexação

Quando o interesse é extrair, excluir ou substituir elementos de objetos é possível fazê-lo usando-se de algum mecanismo de indexação, que dependerá do tipo de objeto manejado. Isto é, usa-se de um mecanismo de localização da posição do elemento.

O que signifa indexar?

Dispor em índice, numa lista que metodicamente indica o conteúdo de alguma coisa; ordenar: indexar os livros de uma biblioteca (Dicio, Dicionário Online de Português).

Em termos gerais, existem seis modos de indexar valores no R:

  1. Nomes;
  2. Valores lógicos;
  3. Inteiros positivos;
  4. Inteiros negativos;
  5. Espaço em branco; e
  6. Zero.

Para indexar elementos ou subconjuntos de objetos no R existem três operadores básicos: \(\color{red}{[ ~~]}\), \(\color{red}{[[~~]]}\) e \(\color{red}{\$}\).

  • O operador \(\color{red}{[~~]}\) permite extrair múltiplos elementos de um objeto, e retornar um novo objeto de mesma classe.

  • O operador \(\color{red}{[[~~]]}\) permite extrair elementos de objetos do tipo lista ou data frames. A classe do objeto extraído não será, necessarriamente, uma lista ou data frame.

  • O operador \(\color{red}{\$}\) permite extrair componentes nomeados de uma lista ou data frame.

5.2 Indexação de vetores

5.2.1 Extrair, excluir e substituir

Para extrair, excluir ou substituir elementos no objeto-vetor usa-se o comando \(\color{red}{[ \color{black}{i} ]}\). Onde o índice i indica a posição do elemento no objeto. O indice i inicia no valor 1. A função \(\color{magenta}{\textbf{c()}}\) pode ser usada para concatenar as posições desejadas dentro de colchetes.

a) Extração por indexação positiva: especifica (entre colchetes) os elementos a serem extraídos.

especie <- c("Acapu", "Araucaria", "Mogno", "Cedro", "Ipe")
diametro <- c(23.0, 27.0, 33.6, 42.6, 52.1)

# Extraindo elementos (usando valores inteiros)
especie[2]                               # Um elemento.
## [1] "Araucaria"

diametro[1:3]                            # Múltiplos elementos (sequenciais).
## [1] 23.0 27.0 33.6

especie[c(1,3,5)]                        # Múltiplos elementos (alternados).
## [1] "Acapu" "Mogno" "Ipe"

diametro[seq(from = 1, to = 5, by = 2)]  # Múltiplos elementos usando seq ().
## [1] 23.0 33.6 52.1

b) Extração por indexação negativa: especifica (entre colchetes) os elementos a serem excluídos, retornando os demais. Deve-se usar o sinal negativo (\(\color{red}{-}\)) para indicar o desejo de excluir um ou mais elementos do objeto-vetor \(\color{red}{[ \color{black}{-i} ]}\).

# Excluindo elementos (usando valores inteiros)
especie[-2]                             # Um elemento.
## [1] "Acapu" "Mogno" "Cedro" "Ipe"

diametro[-(1:3)]                        # Múltiplos elementos (sequenciais).
## [1] 42.6 52.1

especie[-c(1,3,5)]                      # Múltiplos elementos (alternados).
## [1] "Araucaria" "Cedro"

c) Extração por indexação de strings (vetores nomeados): Este mecanismo apenas é possível quando o objeto-vetor possui um atributo de nomes para identificar seus elementos. Pode-se usar a função \(\color{magenta}{\textbf{names()}}\) para atribuír nomes (rótulos) para cada elemento do objeto-vetor. A vantagem disso é facilidade de identificação dos elementos do objeto-vetor.

# Cria o vetor "altura"
altura <- c(1.52, 1.83, 1.74, 1.67, 1.98)
names(altura)
## NULL

# Atribuindo nomes (labels) aos elementos do objeto-vetor
names(altura) <- c("João", "Maria", "José", "Pedro", "Tomé") 
names(altura)
## [1] "João"  "Maria" "José"  "Pedro" "Tomé"

# Extraindo elementos (usando nomes)
altura[c("Maria", "José")]    # Altura de pessoas específicas?
## Maria  José 
##  1.83  1.74

d) Extração por indexação lógica: A extração de elementos no objeto-vetor pode ser feita com uso de operadores lógicos.

Especie <- c(NA, "Araucaria", "Mogno", "Cedro", "Ipe",
             "Tauari", "Jatoba", "Araucaria", "Acapu", NA)
Diametro <- c(23.0, 27.0, 33.6, 42.6, 52.1,
              65.8, 79.6, 45.2, 50.0, 89.8)

# Extrai árvores que não sejam Araucaria
Especie[Especie != "Araucaria"]                      
## [1] NA       "Mogno"  "Cedro"  "Ipe"    "Tauari" "Jatoba" "Acapu"  NA

# Diâmetros > 50cm.
Diametro[Diametro >= 50]                             
## [1] 52.1 65.8 79.6 50.0 89.8

e) Substituição por indexação: Algumas vezes o interesse é substituir um ou mais elemento do objeto-vetor por outro.

Especie <- c(NA, "Araucaria", "Mogno", "Cedro", "Ipe", NA)
Diametro <- c(23.0, 27.0, 33.6, 42.6, 52.1)

# Substitui os NAs
is.na(Especie)
## [1]  TRUE FALSE FALSE FALSE FALSE  TRUE
Especie[is.na(Especie)] <- "Não Identificada"
print(Especie)
## [1] "Não Identificada" "Araucaria"        "Mogno"           
## [4] "Cedro"            "Ipe"              "Não Identificada"

# Altera o diâmetro da posição 3, e atribui 33,5cm.
Diametro[3] <- 33.5

# Altera os diâmetros das posições 4 e 5, e atribui 55,3cm e 63,4cm
Diametro[c(4, 5)] <- c(55.3, 63.4)

5.2.2 Comando especiais para vetores

Função \(\color{magenta}{\textbf{which()}}\): Qual?

\(\color{magenta}{which(\color{black}{x~=~?,~arr.ind~=~FALSE,~useNames~=~TRUE})}\)

A função \(\color{magenta}{\textbf{which()}}\) recebe e avalia expressões lógicas (objeto-vetor lógico) e, fornece a posição dos elementos em que a expressão lógica é verdadeira (TRUE). Os NAs são admitidos pela função, porém são tratados como FALSE.

alfa <- LETTERS
Especie <- c(NA, "Araucaria", "Mogno", "Cedro", "Ipe",
             "Tauari", "Jatoba", "Araucaria", "Acapu", NA)
Diametro <- c(23.0, 27.0, 33.6, 42.6, 52.1,
              65.8, 79.6, 45.2, 50.0, 89.8)

which(alfa == "H")                    # posição da letra "H" no alfabeto
## [1] 8

which(Especie == "Mogno")             # posição do "Mogno"
## [1] 3

which(Diametro >= 50 | Diametro < 25) # posição de árvores com 50 <= d < 25
## [1]  1  5  6  7  9 10

Função \(\color{magenta}{\textbf{which.min()}}\): Qual posição do valor mínimo?

Função \(\color{magenta}{\textbf{which.max()}}\): Qual posição do valor máximo?

Função \(\color{magenta}{\textbf{unique()}}\): Recebe um objeto-vetor e, retorna um vetor sem repetições.

which.max(Diametro)
## [1] 10

which.min(Diametro)
## [1] 1

unique(Especie)
## [1] NA          "Araucaria" "Mogno"     "Cedro"     "Ipe"       "Tauari"   
## [7] "Jatoba"    "Acapu"

Comando \(\color{red}{\textbf{%in%}}\)

É um operador binário, que retorna um vetor boleano (lógico) de tamanho sempre igual ao vetor-esquerdo com indicativo das correspondências verdadeiras (TRUE).

Esp.1 <- c("Acapu", "Araucaria", "Mogno", "Cedro", "Tauari")
Esp.2 <- c("Angelim", "Araucaria", "Tauari")
Diametro <- c(23.0, 27.0, 33.6, 42.6, 52.1)

# vetor direito está contido no esquerdo?
Esp.1 %in% c("Mogno", "Cedro")    
## [1] FALSE FALSE  TRUE  TRUE FALSE
Esp.1 %in% Esp.2
## [1] FALSE  TRUE FALSE FALSE  TRUE
Esp.2 %in% Esp.1
## [1] FALSE  TRUE  TRUE

5.3 Indexação de matrizes

5.3.1 Extrair, excluir e substituir

Para extrair, excluir ou substituir elementos de uma matriz usa-se o comando \(\color{red}{[ \color{black}{i, j} ]}\). Onde o índice i indica linhas e j indica as colunas da matriz.

  • Se o argumento for do tipo \(\color{red}{[ \color{black}{i,~} ]}\) ter-se-á acesso a todos os elementos da linha i especificada.

  • Se o argumento for do tipo \(\color{red}{[ \color{black}{,~j} ]}\) ter-se-á acesso a todos os elementos da coluna j especificada.

  • Se nem o número linha e nem o número da coluna é informado: \(\color{red}{[ \color{black}{~,~} ]}\). A matriz é acessada por completa.

Por exemplo, em uma matriz x o elemento situado na \(1ª\) linha da \(1ª\) coluna pode ser representado por \(x_{11}\), e pode ser acessado fazendo: \(\color{red}{x[ \color{black}{1, 1} ]}\)

Matriz 3x3 \(\begin{bmatrix}x_{11}&x_{12}&x_{13}\\x_{21}&x_{22}&x_{23}\\x_{31}&x_{32}&x_{33}\end{bmatrix}\)

a) Extraindo elementos: Usa-se indexação positiva.

mat <- matrix(1:6, nrow=2, ncol=3, byrow = TRUE, 
              dimnames = list(c("L1", "L2"), 
                              c("C1", "C2", "C3")))
# Extraindo elementos
mat[2,2]                      # elemento da linha 2 e coluna 2.
## [1] 5

mat[2, ]                      # todos elementos da linha 2.
## C1 C2 C3 
##  4  5  6

mat[, 3]                      # todos elementos da coluna 3.
## L1 L2 
##  3  6

mat[c(1,2), c(2,3)]           # elementos de L1 e L2, e C2 e C3.
##    C2 C3
## L1  2  3
## L2  5  6

b) Excluindo elementos: Usa-se indexação negativa.

mat <- matrix(1:6, nrow=2, ncol=3, byrow = TRUE, 
              dimnames = list(c("L1", "L2"), 
                              c("C1", "C2", "C3")))
print(mat)
##    C1 C2 C3
## L1  1  2  3
## L2  4  5  6

# Excluindo elementos
mat[,c(-1,-3)]                # exclui as colunas 1 e 3.
## L1 L2 
##  2  5

mat[-2,-1]                    # exclui a linha 2 e a coluna 1.
## C2 C3 
##  2  3

c) Substituindo elementos

mat <- matrix(1:6, nrow=2, ncol=3, byrow = TRUE, 
              dimnames = list(c("L1", "L2"), 
                              c("C1", "C2", "C3")))
print(mat)
##    C1 C2 C3
## L1  1  2  3
## L2  4  5  6

# substitui o elemento da posição 1, por zero.
mat[1, 1] <- 0
print(mat)   
##    C1 C2 C3
## L1  0  2  3
## L2  4  5  6

# substitui os elementos das posiçoes 1 e 5, por zero.
# Obs.: observe a forma de contagem das posições!
mat[c(1,5)] <- c(0,0)
print(mat)  
##    C1 C2 C3
## L1  0  2  0
## L2  4  5  6

5.4 Indexação de data frames

5.4.1 Extrair, excluir, substituir

O acesso a um determinado vetor em um data frame pode ser realizado utilizando-se do comando \(\color{red}{[~\color{black}{ }~]}\) (similar às matrizes) ou dos comandos \(\color{red}{[[~ \color{black}{ }~]]}\) e \(\color{red}{\$}\) (similar às listas). As funções \(\color{magenta}{\textbf{attach()}}\) (attachment) e \(\color{magenta}{\textbf{with()}}\) podem ser usadas para facilitar o acesso a esses vetores.

invFlor.2 <- data.frame(
  especie = c("Acapu", "Araucaria", "Mogno", "Cedro", "Ipe"), 
  diametro = c(23.0, 27.0, 33.6, 42.6, 52.1),
  altura = c(8.4, 8.7, 9.1, 13.2, 15.4),
  cortar = c("Não", "Não", "Não", "Não", "Sim"),
  stringsAsFactors = TRUE)

print(invFlor.2)
##     especie diametro altura cortar
## 1     Acapu     23.0    8.4    Não
## 2 Araucaria     27.0    8.7    Não
## 3     Mogno     33.6    9.1    Não
## 4     Cedro     42.6   13.2    Não
## 5       Ipe     52.1   15.4    Sim

Comandos \(\color{red}{[~~]}\) e \(\color{red}{[[~~]]}\)

invFlor.2[2,1]                                    # similar as matrizes
## [1] Araucaria
## Levels: Acapu Araucaria Cedro Ipe Mogno

invFlor.2[[2,1]]                                  # similar as listas
## [1] Araucaria
## Levels: Acapu Araucaria Cedro Ipe Mogno

invFlor.2[, c(1,2,4), drop=FALSE]                 # drop = FALSE
##     especie diametro cortar
## 1     Acapu     23.0    Não
## 2 Araucaria     27.0    Não
## 3     Mogno     33.6    Não
## 4     Cedro     42.6    Não
## 5       Ipe     52.1    Sim

invFlor.2[c(1,2), c("especie","diametro")]        # mais específico
##     especie diametro
## 1     Acapu       23
## 2 Araucaria       27

Comando \(\color{red}{\$}\)

invFlor.2$diametro              # acessa a coluna diâmetro.
## [1] 23.0 27.0 33.6 42.6 52.1

invFlor.2$cortar                # acessa a coluna cortar.
## [1] Não Não Não Não Sim
## Levels: Não Sim

# acessa a coluna cortar e extrai os elementos da posição 4 e 5.
invFlor.2$cortar[c(4,5)]        
## [1] Não Sim
## Levels: Não Sim

Usando operadores lógicos

Os operadores lógicos podem ser usados para extrair informações específicas do data frame. Inicialmente, observar-se-á o retorno boleano (TRUE ou FALSE):

# Quais valores de altura são maiores do que 10m?
invFlor.2$altura > 10
## [1] FALSE FALSE FALSE  TRUE  TRUE

# Quais valores de diâmetro são maiores ou iguais a 50cm?
invFlor.2$diametro >= 50
## [1] FALSE FALSE FALSE FALSE  TRUE

# Quais árvores possuem “Sim” para “Corte”?
invFlor.2$cortar == "Sim"
## [1] FALSE FALSE FALSE FALSE  TRUE

No entanto, na maioria das vezes deseja-se extrair os elementos:

# Quais valores de altura são maiores do que 10m?
invFlor.2[invFlor.2$altura > 10, ]
##   especie diametro altura cortar
## 4   Cedro     42.6   13.2    Não
## 5     Ipe     52.1   15.4    Sim

# Quais valores de diâmetro são maiores ou iguais a 50cm?
invFlor.2[invFlor.2$diametro >= 50,]
##   especie diametro altura cortar
## 5     Ipe     52.1   15.4    Sim

# Quais árvores possuem “Sim” para “Corte”?
invFlor.2[invFlor.2$cortar == "Sim",]
##   especie diametro altura cortar
## 5     Ipe     52.1   15.4    Sim

# Extrai árvores com diâmetros < 50cm e não disponíveis p/ corte
invFlor.2[invFlor.2$diametro < 50 & invFlor.2$cortar == "Não", ]
##     especie diametro altura cortar
## 1     Acapu     23.0    8.4    Não
## 2 Araucaria     27.0    8.7    Não
## 3     Mogno     33.6    9.1    Não
## 4     Cedro     42.6   13.2    Não

5.4.2 Adicionar colunas e linhas

Adicionando colunas ao DF

# Adicionando a coluna “Protegida”
protegida <-  c("Sim", "Sim", "Sim", "Não", "Não")
invFlor.2$protegida <- protegida
print(invFlor.2)
##     especie diametro altura cortar protegida
## 1     Acapu     23.0    8.4    Não       Sim
## 2 Araucaria     27.0    8.7    Não       Sim
## 3     Mogno     33.6    9.1    Não       Sim
## 4     Cedro     42.6   13.2    Não       Não
## 5       Ipe     52.1   15.4    Sim       Não

Adicionando linhas ao DF

Para adicionar linhas a um data frame há uma restrição: “não é possível adicionar novos níveis de fator para vetores da classe factor. Para exemplificar, tentar-se-á inserir o seguinte vetor-linha: (”Castanha“, 150.9, 25.6,”Não“,”Sim“) na linha 1. No entanto, antes estudaremos alguns pontos:

1) A coluna “espécie” pertence a classe factor e, originalmente, não possui o nível de fator “Castanha”; e 2) A coluna “cortar” pertence a classe factor e, originalmente, já possui o nível de fator “Não”.

O que aconteceu?

Aparecerá uma mensagem de erro atestando que o nível de fator “Castanha” é inválido. Isto porque, a espécie \(\color{red}{Castanha}\) não existe no data frame original, sendo considerada um novo nível de fator. Assim, NA será impresso no lugar do nome da \(\color{red}{Castanha}\).

Idealmente, para evitar problemas deste tipo, pode-se manter todas as colunas qualitativas como character. Para tanto, deve-se usar o argumento stringsAsFactors = FALSE.

str(invFlor.2)
## 'data.frame':    5 obs. of  5 variables:
##  $ especie  : Factor w/ 5 levels "Acapu","Araucaria",..: 1 2 5 3 4
##  $ diametro : num  23 27 33.6 42.6 52.1
##  $ altura   : num  8.4 8.7 9.1 13.2 15.4
##  $ cortar   : Factor w/ 2 levels "Não","Sim": 1 1 1 1 2
##  $ protegida: chr  "Sim" "Sim" "Sim" "Não" ...

invFlor.2[1,] <- c("Castanha", 150.9, 25.6, "Não", "Sim")
## Warning in `[<-.factor`(`*tmp*`, iseq, value = "Castanha"): invalid factor
## level, NA generated
print(invFlor.2)
##     especie diametro altura cortar protegida
## 1      <NA>    150.9   25.6    Não       Sim
## 2 Araucaria       27    8.7    Não       Sim
## 3     Mogno     33.6    9.1    Não       Sim
## 4     Cedro     42.6   13.2    Não       Não
## 5       Ipe     52.1   15.4    Sim       Não

invFlor.2$especie <- as.character(invFlor.2$especie)

invFlor.2[1,] <- c("Castanha", 150.9, 25.6, "Não", "Sim")

print(invFlor.2)
##     especie diametro altura cortar protegida
## 1  Castanha    150.9   25.6    Não       Sim
## 2 Araucaria       27    8.7    Não       Sim
## 3     Mogno     33.6    9.1    Não       Sim
## 4     Cedro     42.6   13.2    Não       Não
## 5       Ipe     52.1   15.4    Sim       Não

5.4.3 Funções \(\color{magenta}{\textbf{attach()}}\), \(\color{magenta}{\textbf{detach()}}\) e \(\color{magenta}{\textbf{with()}}\)

Função \(\color{magenta}{\textbf{attach()}}\)

A função \(\color{magenta}{\textbf{attach()}}\) oferece acesso direto aos vetores do data frame. Para finalizar seu uso deve-se utilizar a função \(\color{magenta}{\textbf{detach()}}\).

attach(invFlor.2)
## The following objects are masked _by_ .GlobalEnv:
## 
##     altura, cortar, diametro, especie, protegida
diametro              # acessa direto ao diâmetro.
## [1] 23.0 27.0 33.6 42.6 52.1

cortar                # acessa direto a coluna cortar.
## [1] "Não" "Não" "Não" "Não" "Sim"
detach(invFlor.2)

Função \(\color{magenta}{\textbf{with()}}\)

# acessa coluna especie
with(invFlor.2, especie)
## [1] "Castanha"  "Araucaria" "Mogno"     "Cedro"     "Ipe"

# acessa elementos específicos na coluna
with(invFlor.2, especie[4:5])   
## [1] "Cedro" "Ipe"

# pode-se usar para aplicar funções
with(invFlor.2, mean(altura))
## Warning in mean.default(altura): argument is not numeric or logical:
## returning NA
## [1] NA

5.4.4 Função \(\color{magenta}{\textbf{subset()}}\)

Função \(\color{magenta}{\textbf{subset()}}\): Extrai um subconjunto de vetores, matrizes e data frames que atendem às condições.

A função \(\color{magenta}{\textbf{subset()}}\) também pode ser usada para extrair elementos de um data frame usando de operadores lógicos. Para estudar a função usar-se-á do famoso conjunto de dados de flores de iris (iris data set). O conjunto de dados é composto de 150 observações (instâncias) e 5 variáveis (Sepal.Length, Sepal.Width, Petal.Length e Petal.Width, Species), de 50 flores de cada espécie de íris (Iris setosa, Iris versicolor e Iris virginica).

data("iris")
head(iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa
tail(iris)
##     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
## 145          6.7         3.3          5.7         2.5 virginica
## 146          6.7         3.0          5.2         2.3 virginica
## 147          6.3         2.5          5.0         1.9 virginica
## 148          6.5         3.0          5.2         2.0 virginica
## 149          6.2         3.4          5.4         2.3 virginica
## 150          5.9         3.0          5.1         1.8 virginica
str(iris)
## 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
dim(iris)
## [1] 150   5
# flores com Sepal.Length > 7.5, mantendo as colunas Species e Sepal.Length.
subset(iris, Sepal.Length > 7.5, select = c(Species, Sepal.Length))
##       Species Sepal.Length
## 106 virginica          7.6
## 118 virginica          7.7
## 119 virginica          7.7
## 123 virginica          7.7
## 132 virginica          7.9
## 136 virginica          7.7

# flores de setosa com Sepal.Width < 3, mantendo as colunas 
# Species e Sepal.Width.
subset(iris, Species == "setosa" & Sepal.Width < 3, 
       select = c(Species, Sepal.Width))
##    Species Sepal.Width
## 9   setosa         2.9
## 42  setosa         2.3

5.4.5 Função \(\color{magenta}{\textbf{split()}}\)

A divisão de data frames pode ser realizada por meio da função \(\color{magenta}{\textbf{split()}}\). Para tanto, sirva-se de dois argumentos básicos: i) data frame que se almeja dividir; ii) fator a ser considerado para a divisão.

protegida <- split(invFlor.2,invFlor.2$protegida)

print(protegida)
## $Não
##   especie diametro altura cortar protegida
## 4   Cedro     42.6   13.2    Não       Não
## 5     Ipe     52.1   15.4    Sim       Não
## 
## $Sim
##     especie diametro altura cortar protegida
## 1  Castanha    150.9   25.6    Não       Sim
## 2 Araucaria       27    8.7    Não       Sim
## 3     Mogno     33.6    9.1    Não       Sim

5.5 Indexação de listas

A indexação de lista pode ser feita com uso dos comando \(\color{red}{[[~~]]}\) e \(\color{red}{\$}\). Ainda, para acessar subíndices dos componentes da lista pode-se fazer: \(\color{red}{[[~~]][~~]}\). Para exemplificar, considere a lista list.2 que contém 3 componentes (vetor, matriz e DF):

# Uma lista cujos componentes não estão nomeados
list.2 <- list(diametro, mat.8, invFlor.1)

print(list.2)
## [[1]]
## [1] 23.0 27.0 33.6 42.6 52.1
## 
## [[2]]
##    C1 C2 C3
## L1  1  2  3
## L2  4  5  6
## 
## [[3]]
##     especie diametro altura cortar
## 1     Acapu     23.0    8.4    Não
## 2 Araucaria     27.0    8.7    Não
## 3     Mogno     33.6    9.1    Não
## 4     Cedro     42.6   13.2    Não
## 5       Ipe     52.1   15.4    Sim

list.2[[1]]             
## [1] 23.0 27.0 33.6 42.6 52.1

list.2[[2]][1,]         
## C1 C2 C3 
##  1  2  3

list.2[[3]][diametro > 50 & cortar == "Sim", ]
##   especie diametro altura cortar
## 5     Ipe     52.1   15.4    Sim

Se a lista tiver seus componente nomeados o acesso é facilitado pelo uso do comando \(\color{red}{\$}\):

list.2 <- list(diametro=diametro, matriz=mat.8, DF=invFlor.1)

print(list.2)
## $diametro
## [1] 23.0 27.0 33.6 42.6 52.1
## 
## $matriz
##    C1 C2 C3
## L1  1  2  3
## L2  4  5  6
## 
## $DF
##     especie diametro altura cortar
## 1     Acapu     23.0    8.4    Não
## 2 Araucaria     27.0    8.7    Não
## 3     Mogno     33.6    9.1    Não
## 4     Cedro     42.6   13.2    Não
## 5       Ipe     52.1   15.4    Sim

list.2$diametro           
## [1] 23.0 27.0 33.6 42.6 52.1

list.2$matriz[1,]
## C1 C2 C3 
##  1  2  3

list.2$DF[diametro > 50 & cortar == "Sim", ]
##   especie diametro altura cortar
## 5     Ipe     52.1   15.4    Sim

Substituindo elementos de componentes da lista

# substitui por 50 e 60 no diâmetro
list.2$diametro[c(3,5)] <- c(50, 60)

print(list.2)
## $diametro
## [1] 23.0 27.0 50.0 42.6 60.0
## 
## $matriz
##    C1 C2 C3
## L1  1  2  3
## L2  4  5  6
## 
## $DF
##     especie diametro altura cortar
## 1     Acapu     23.0    8.4    Não
## 2 Araucaria     27.0    8.7    Não
## 3     Mogno     33.6    9.1    Não
## 4     Cedro     42.6   13.2    Não
## 5       Ipe     52.1   15.4    Sim

Excluindo componentes da lista

list.2$DF <- NULL          # excluindo todo componente DF
print(list.2)
## $diametro
## [1] 23.0 27.0 50.0 42.6 60.0
## 
## $matriz
##    C1 C2 C3
## L1  1  2  3
## L2  4  5  6

# excluindo colunas 2 e 3 do componente matriz
list.2$matriz <- list.2$matriz[,-c(2,3)]
print(list.2)
## $diametro
## [1] 23.0 27.0 50.0 42.6 60.0
## 
## $matriz
## L1 L2 
##  1  4

6 Criando funções no R

O ambiente R possui muitas funções interativas e prontas disponíveis em inúmeros pacotes, para o uso fácil e prático pelos usuários. Não obstante, em algumas situações pode-se desejar criar a própria função. Para tanto, deve-se utilizar a função \(\color{magenta}{function() \color{blue}{\{~\}}}\) disponível no R-base (R CORE TEAM, 2017). Entre parênteses devem ser inseridos os argumento(s) da função, sobre os quais irá trabalhar o código descrito entre chaves \(\color{blue}{\{~\}}\). Opcionalmente, no escopo da função pode-se usar a função \(\color{magenta}{return()}\), e especificar entre os parênteses a(s) saída(s) desejada(s) ao se aplicar a função.

\(\textbf{Sintaxe}\)

\(\color{magenta}{function(\color{black}{arglist~=~arg1,~arg2~,~...,~argn})}\) \(\color{blue}{\{}\)

\(\color{black}{expr}\)

\(\color{magenta}{return(\color{black}{value})}\)

\(\color{blue}{\}}\)

\(\color{black}{\textbf{arglist}}\) = um argumento ou lista de argumentos sobre o(s) qual(is) irá atuar o código expr;

\(\color{black}{\textbf{expr}}\) = uma expressão ou código a ser usado sobre os argumentos da função;

\(\color{black}{\textbf{return}}\) = função que específica o retorno da função; e

\(\color{black}{\textbf{value}}\) = uma expressão que representa a saída desejada.

1. Criando uma função para obter a \(\color{red}{\textbf{média aritmética}}\) de um vetor x qualquer:

Media <- function(x){
  n = length(x)
  Soma=sum(x)
  Media=Soma/n
  
  return(Media)                                
}

Dado um objeto-vetor de diâmetros de árvores pode-se calcular a média usando a função:

diametro <- c(23.4, 54.3, 45.1, 67.1, 34.7)
Media(diametro)          
## [1] 44.92

2. Criando uma função para obter o \(\color{red}{\textbf{coeficiente de variação}}\) de um vetor x qualquer:

CV <- function(x){
  Media = sum(x)/length(x)
  DP = sqrt(sum((x-mean(x))^2)/(length(x)-1))
  CV = (DP/Media)*100
  
  return(CV)                                                                            
}

Para o mesmo vetor de diâmetros de árvores pode-se calcular o CV:

CV(diametro)          
## [1] 37.70612

3. Criando uma função para obter várias \(\color{red}{\textbf{estatísticas descritivas}}\):

descritivas.1 <-
  function(x){
  n <- length(x)
  Soma <- sum(x)
  Media <- round(sum(x)/n, digits=2)
  Variancia <- var(x)
  DP <- round(sd(x), digits=2)
  CV <- round((DP/Media)*100,digits=2)
  Minimo <- min(x)
  Quartil1 <- quantile(x,0.25)
  Mediana <- median(x)
  Quartil3 <- quantile(x,0.75)
  Interquatil <- Quartil3-Quartil1
  Maximo <- max(x)
  
  return(list(n=n,Media=Media,DP=DP,CV=CV,Min=Minimo,
              Q1=Quartil1,Md=Mediana,Q3=Quartil3,
              Interquatil=Interquatil,Max=Maximo))
}

Considerando o conjunto de dados trees pode-se aplicar, por exemplo, a função para obter as estatísticas descritivas para a variável volume. O parâmetro x da função recebe o vetor volume no argumento x e, retorna uma lista com as estatísticas descritivas. Para obter as mesmas estatísticas deve-se aplicar a função a cada variável de interesse, individualmente.

descritivas.1(trees$Volume)
## $n
## [1] 31
## 
## $Media
## [1] 30.17
## 
## $DP
## [1] 16.44
## 
## $CV
## [1] 54.49
## 
## $Min
## [1] 10.2
## 
## $Q1
##  25% 
## 19.4 
## 
## $Md
## [1] 24.2
## 
## $Q3
##  75% 
## 37.3 
## 
## $Interquatil
##  75% 
## 17.9 
## 
## $Max
## [1] 77

Mas, seria possível criar uma função para retornar várias estatísticas para diversas variáveis simultâneamente? Agora, é apresentada uma função que faz exatamente isso. Assim, pode-se usar uma \(\color{magenta}{function() \color{blue}{\{~\}}}\) no argumento FUN da função \(\color{magenta}{\textbf{apply()}}\). Além disso, MARGIN é definida com inteiro igual a 2, para que a função em FUN seja aplicada às colunas do data frame.

descritivas.2 <- 
  apply(trees,MARGIN = 2, FUN = 
          function(x){
            n <- length(x)
            Soma <- sum(x)
            Media <- round(sum(x)/n, digits=2)
            Variancia <- var(x)
            DP <- round(sd(x), digits=2)
            CV <- round((DP/Media)*100,digits=2)
            Minimo <- min(x)
            Quartil1 <- quantile(x,0.25)
            Mediana <- median(x)
            Quartil3 <- quantile(x,0.75)
            Interquatil <- Quartil3-Quartil1
            Maximo <- max(x)
            
            return(list(n=n,Media=Media,DP=DP,CV=CV,Min=Minimo,
                        Q1=Quartil1,Md=Mediana,Q3=Quartil3,
                        Interquatil=Interquatil,Max=Maximo))
})

descritivas.2
## $Girth
## $Girth$n
## [1] 31
## 
## $Girth$Media
## [1] 13.25
## 
## $Girth$DP
## [1] 3.14
## 
## $Girth$CV
## [1] 23.7
## 
## $Girth$Min
## [1] 8.3
## 
## $Girth$Q1
##   25% 
## 11.05 
## 
## $Girth$Md
## [1] 12.9
## 
## $Girth$Q3
##   75% 
## 15.25 
## 
## $Girth$Interquatil
## 75% 
## 4.2 
## 
## $Girth$Max
## [1] 20.6
## 
## 
## $Height
## $Height$n
## [1] 31
## 
## $Height$Media
## [1] 76
## 
## $Height$DP
## [1] 6.37
## 
## $Height$CV
## [1] 8.38
## 
## $Height$Min
## [1] 63
## 
## $Height$Q1
## 25% 
##  72 
## 
## $Height$Md
## [1] 76
## 
## $Height$Q3
## 75% 
##  80 
## 
## $Height$Interquatil
## 75% 
##   8 
## 
## $Height$Max
## [1] 87
## 
## 
## $Volume
## $Volume$n
## [1] 31
## 
## $Volume$Media
## [1] 30.17
## 
## $Volume$DP
## [1] 16.44
## 
## $Volume$CV
## [1] 54.49
## 
## $Volume$Min
## [1] 10.2
## 
## $Volume$Q1
##  25% 
## 19.4 
## 
## $Volume$Md
## [1] 24.2
## 
## $Volume$Q3
##  75% 
## 37.3 
## 
## $Volume$Interquatil
##  75% 
## 17.9 
## 
## $Volume$Max
## [1] 77

Pode-se melhorar a saída das estatísticas:

do.call(rbind, descritivas.2)
##        n  Media DP    CV    Min  Q1    Md   Q3    Interquatil Max 
## Girth  31 13.25 3.14  23.7  8.3  11.05 12.9 15.25 4.2         20.6
## Height 31 76    6.37  8.38  63   72    76   80    8           87  
## Volume 31 30.17 16.44 54.49 10.2 19.4  24.2 37.3  17.9        77

7 Estruturas de controle

7.1 Instrução condicional

7.1.1 Comandos \(\color{magenta}{\textbf{if}}\), \(\color{magenta}{\textbf{if-else}}\) e \(\color{magenta}{\textbf{if-elseif-else}}\)

De modo geral, pode-se identificar três principais variações de instruções condicionais, isto é, \(\color{magenta}{if}\), \(\color{magenta}{if-else}\) e \(\color{magenta}{if-elseif-else}\). A estrutura \(\color{magenta}{if() \color{blue}{\{~\}}}\) condiciona a execução de uma lista de instruções (código) em função de uma condição booleana (verdadeira ou falsa). Assim, a aplicação da condicional \(\color{magenta}{function() \color{blue}{\{~\}}}\) requer duas argumentações básicas: a) a condição a ser satisfeita, descrita entre parênteses; e b) uma ou mais instrução(ões), expressas entre chaves \(\color{blue}{\{~\}}\), que deverão ser executadas caso a condição booleana seja verdadeira. Para mais informações faça ?if.

Alternativamente, a condição \(\color{magenta}{if()}\) pode ser usada em conjunto com \(\color{magenta}{else \color{blue}{\{~\}}}\). Neste caso, tem-se a seguinte estrutura: \(\color{magenta}{if(~)\color{blue}{\{~\}}} \color{magenta}{else}\color{blue}{\{~\}}\). Assim, a condição será examinada a cada passagem pela estrutura \(\color{magenta}{if()}\), caso seja satisfeita (VERDADEIRA) a lista de instruções entre chaves será executada. Do contrário, se for FALSA, será executado o código atribuído ao comando \(\color{magenta}{else\color{blue}{\{~\}}}\). A instrução \(\color{magenta}{if(~)\color{blue}{\{~\}}} \color{magenta}{elseif()}\color{blue}{\{~\}}\color{magenta}{else}\color{blue}{\{~\}}\) é outra variação da estrutura condicional \(\color{magenta}{if()}\), sendo usada quando se deseja executar mais de uma condicional através de instruções aninhadas. Deve-se atentar para o cuidado de saber a qual \(\color{magenta}{if()}\) está atrelado cada \(\color{magenta}{else\color{blue}{\{\}}}\).

Como usar a instrução condicional?

Uso da instrução \(\color{magenta}{if() \color{blue}{\{~\}}}\)

x <- 9
if (x < 10){                 # Se =  "x" < 10    
  print(x)                   # Imprima = "x"
  print("É menor do que 10") # Faça = imprima "É menor do que 10"
}                            # fim Se
## [1] 9
## [1] "É menor do que 10"

Uso da instrução \(\color{magenta}{if(~)\color{blue}{\{~\}}} \color{magenta}{else}\color{blue}{\{~\}}\)

x <- 11
if (x <= 10){                     # Se =  "x" <= 10
  cat("É menor ou igual a 10")    # Imprima = "É menor ou igual a 10"
}else{                            # do contrário
  cat("É maior do que 10")        # Imprima = "É maior do que 10"
}                                 # fim Se
## É maior do que 10

Uso da instrução \(\color{magenta}{if(~)\color{blue}{\{~\}}} \color{magenta}{elseif()}\color{blue}{\{~\}}\color{magenta}{else}\color{blue}{\{~\}}\) - ifs aninhados

x <- 9
if (x == 10){                     # Se =  "x" == 10
  print("É igual a 10")           # Imprima = "É igual a 10"
} else if (x > 10) {              # Se =  "x" > 10
  print("É maior do que 10")      # Imprima = "É maior do que 10"
} else {                          # do contrário
  print("É menor do que 10")      # Imprima = "É menor do que 10"
}                                 # fim Se
## [1] "É menor do que 10"

As instruções condicionais podem ser usadas dentro de funções:

dap1 <- 64
dap2 <- 43

categoria <- function (x)
if (x >= 50){
  print(paste("Cortar =", x))
} else {
  print(paste("Protegida =", x))
}

categoria(dap1)
## [1] "Cortar = 64"
categoria(dap2)
## [1] "Protegida = 43"

Em outras situações, pode-se requerer usar alguma das 3 variações de instrução condicional a um vetor numérico, porém ocorrerá uma menasagem de erro alertando que a condição do \(\color{magenta}{if()}\) tem comprimento maior do que 1, e somente o primeiro elemento do vetor será considerado para execução do código. Isto é, o uso das variações \(\color{magenta}{if()}\) está condicionado a vetores de comprimento igual a um, não podendo ser um NA. Para fns ilustrativos, a seguir criou-se um vetor x qualquer com seis elementos e, em seguida foi elaborada uma estrutura condicional com a seguinte condição booleana if(x == 10), que se verdadeira retorna É igual a 10. De fato, o desejável seria que a condição booleana fosse avaliada para cada elemento do vetor x, porém isso não acontece. Ao executar o comando surge uma mensagem de erro informando que a condição tem comprimento maior do que 1 e somente o primeiro elemento do vetor x será usado, ou seja, a condição booleana foi avaliada apenas para o número 10, cujo retorno é É igual a 10. Assim, caso a intenção seja aplicar uma condicional a um vetor de comprimento maior do que 1 deve-se utilizar da função \(\color{magenta}{ifelse()}\).

x <- c(10, 9, 8, 10, 15, 16)
if (x == 10){
  print("É igual a 10")
}else{
  print("Não é igual a 10")
}
## Warning in if (x == 10) {: a condição tem comprimento > 1 e somente o
## primeiro elemento será usado
## [1] "É igual a 10"

7.1.2 Comando \(\color{magenta}{\textbf{ifelse()}}\)

Quando o interesse é operar sobre vetores de comprimento maior do que 1, a alternativa é usar a função vetorizada \(\color{magenta}{ifelse()}\). Assim, a condição booleana opera sobre cada elemento do vetor:

\(\textbf{Sintaxe}\)

\(\color{magenta}{ifelse(\color{black}{test~=~?,~yes~=~?,~no~=~?})}\)

\(\color{black}{\textbf{test}}\) = um objeto que pode ser coagido para o modo lógico;

\(\color{black}{\textbf{yes}}\) = instrução a ser retornada quando a condição for VERDADEIRA; e

\(\color{black}{\textbf{no}}\) = instrução a ser executada quando a condição for FALSA.

Retornando, ao exemplo do vetor numérico x será usada a função \(\color{magenta}{ifelse()}\):

x <- c(10, 9, 8, 10, 15, 16)
ifelse(test=(x == 10), yes="É igual a 10", no="Não é igual a 10")
## [1] "É igual a 10"     "Não é igual a 10" "Não é igual a 10"
## [4] "É igual a 10"     "Não é igual a 10" "Não é igual a 10"

O exemplo a seguir simula uma situação de análise de um censo florestal para fins de licenciamento de Plano de Manejo Florestal Sustentável (PMFS). A ideia é identificar as árvores passíveis de exploração legal, considerando apenas dois critérios:

a) o atendimento ao diâmetro mínimo de corte (\(\color{red}{DMC}\) \(\geq\) \(\color{red}{50~cm}\)) (BRASIL, 2009); e

b) se a espécie é \(\color{red}{protegida~por~lei}\). Agora ao invés de um simples vetor tem-se um data frame com quatro variáveis.

invFlor.3 <- data.frame(
  especie = c("Acapu", "Araucaria", "Mogno", "Cedro", "Ipe"), 
  diametro = c(23.0, 27.0, 33.6, 42.6, 52.1),
  altura = c(8.4, 8.7, 9.1, 13.2, 15.4),
  protegida = c("Sim", "Sim", "Sim", "Não", "Não"),
  stringsAsFactors = FALSE)

# solução
ifelse(test=(invFlor.3$diametro >= 50 & invFlor.3$protegida == "Não"), 
       yes="Pode Explorar", no="Não Pode Explorar")
## [1] "Não Pode Explorar" "Não Pode Explorar" "Não Pode Explorar"
## [4] "Não Pode Explorar" "Pode Explorar"

7.2 Estruturas de repetição

Em algumas situações você pode se deparar com a necessidade de executar um mesmo código ou parte de um código repetidamente, ou mesmo, até que uma determinada condição seja satisfeita. No entanto, reescrever um código várias vezes pode ser bastante trabalhoso e, em certas circunstâncias impraticável. Assim, pode-se usar de estruturas de controle de fluxo disponíveis no R-base. Tais estruturas possibilitam ao usuário executar repetidas vezes algum trecho ou o código inteiro de um algoritmo, sob ou não determina(s) condição(ões). Para tanto, cria-se looping (laços de repetição) para que a repetição seja executada tantas vezes quanto forem necessárias. Os principais comandos de controle de fluxo no R são: i) \(\color{magenta}{while}\) (enquanto); ii) \(\color{magenta}{for}\) (para); e iii) \(\color{magenta}{repeat}\) (repita). Para saber mais sobre controle de fluxo no R digite: ?Control.

7.2.1 Comando \(\color{magenta}{\textbf{while()}}\)

O comando \(\color{magenta}{while}\) (enquanto) é uma estrutura de controle de fluxo no R que tem a seguinte estrutura: \(\color{magenta}{while(~)\color{blue}{\{~\}}}\). O comando inicia com a inserção de uma condição booleana entre parênteses. Em seguida, o código é descrito entre chaves, o qual será executado repetidamente ENQUANTO a condição booleana for VERDADEIRA.

Aplicando o comando \(\color{magenta}{while(~)\color{blue}{\{~\}}}\)

x <- 2          # um escalar "x" (valor inicial das sucessivas iterações),
while(x < 10){  # enquanto = "x" for < 10 (condição booleana),
  x <- x+2      # faça = x+2 enquanto a condição x < 10 seja verdadeira,
  print(x)      # imprima = reporte os resultados das iterações de x+2,
}               # fim Enquanto
## [1] 4
## [1] 6
## [1] 8
## [1] 10

Entendendo as iterações:

Pulando um laço do loop \(\color{magenta}{while(~)\color{blue}{\{~\}}}\) – Usando o argumento next na condicional \(\color{magenta}{if(~)\color{blue}{\{~\}}}\):

x <- 2           # um escalar "x" (valor inicial das sucessivas iterações),
while(x < 10){   # enquanto = "x" for < 10 (condição booleana),
  x <- x+2       # faça = x+2 enquanto a condição x < 10 seja verdadeira,
  if(x==8){next} # se, próximo = pule o laço se x == 8, ainda sim faça x+2,
  print(x)       # imprima = reporte os resultados das iterações de x+2,
}                # fim Enquanto
## [1] 4
## [1] 6
## [1] 10

Entendendo as iterações:

Quebrando um laço do loop \(\color{magenta}{while(~)\color{blue}{\{~\}}}\) – Usando o argumento break na condicional \(\color{magenta}{if(~)\color{blue}{\{~\}}}\):

x <- 2            # um escalar "x" (valor inicial das sucessivas iterações),
while(x < 10){    # enquanto = "x" for < 10 (condição booleana),
  if(x==8){break} # se, quebre = Pare de executar x+2, se x == 8,
  x <- x+2        # faça = x+2 enquanto x < 10 e, se x == 8 seja verdade,
  print(x)        # imprima = reporte os resultados das iterações de x+2,
}                 # fim Enquanto
## [1] 4
## [1] 6
## [1] 8

Entendendo as iterações:

7.2.2 Comando \(\color{magenta}{\textbf{for()}}\)

O comando \(\color{magenta}{for()}\) (para) é uma estrutura de controle de fluxo no R, que \(\color{magenta}{for()}\) inicia com a especificação, entre parênteses, do nome da variável de iteração e do vetor ou lista de elementos. Em seguida, entre chaves descreve-se o bloco de códigos que será executado a cada iteração (loop).

\(\textbf{Sintaxe}\)

\(\color{magenta}{for(variavel~in~sequencia)\color{blue}{\{codigo\}}}\)

\(\color{black}{\textbf{variável}}\) = nome da variável de iteração;

\(\color{black}{\textbf{sequência}}\) = vetor ou lista de valores com i elementos; e

\(\color{black}{\textbf{código}}\) = código a ser repetido sob cada elemento i da sequência, a cada iteração.

O pacote magicfor (MAKIYAMA, 2016) dispõe de funções interessantes para armazenar os resultados das iterações dos loops \(\color{magenta}{for()}\). A seguir a implementação de um loop e criação de um data frame com a função \(\color{magenta}{magic\_result\_as\_dataframe()}\). No data frame é adicionada a variável de iteração \(i\) e os resultados da operação \(i^3\):


for(i in 1:4){              # para = cada elemento “i” do vetor 1:4,
  cub <- i^3                # calcule: “i^3” e add ao objeto "cub",
  print(cub)                # faça = imprima o objeto "cub",
}                           # fim Para
magic_result_as_dataframe() # um df com os resultados das iterações.
##   i cub
## 1 1   1
## 2 2   8
## 3 3  27
## 4 4  64

Entendendo as iterações:

O comando a seguir produz o mesmo efeito:

x <- c(1, 2, 3, 4)          # cria um vetor "x" para ser usado em seq,

for(i in x){                # para = cada elemento “i” do vetor "x",
  cub <- i^3                # calcule: “i^3” e add ao objeto "cub",
  print(cub)                # faça = imprima o objeto "cub",
}                           # fim Para
magic_result_as_dataframe() # um df com os resultados das iterações.
##   i cub
## 1 1   1
## 2 2   8
## 3 3  27
## 4 4  64

Cria um vetor x a ser inserido em seq e imprime \(i^3\) e \(i*i\):

x <- c(1, 2, 3, 4)          # cria um vetor "x" para ser usado em seq,

for(i in x){                # para: cada elemento “i” do vetor "x",
  cub <- i^3                # faça:calcule i^3 e add ao objeto "cub",
  prod <- i*i               # faça: calcule i*i e add ao objeto "prod",
  put(cub, prod)            # armazene: os valores da iteração,
}                           # fim Para
## cub: 1, prod: 1
## cub: 8, prod: 4
## cub: 27, prod: 9
## cub: 64, prod: 16
magic_result_as_dataframe() # um df com os resultados das iterações.
##   i
## 1 1
## 2 2
## 3 3
## 4 4

Cria um vetor x vazio e atribui-se o resultado do produto (\(i*i\)) às posições i do vetor. É interessante observar o que acontece quando executa-se a função dentro e fora do comando. Para o exemplo, quando usada a função \(\color{magenta}{print()}\) dentro do loop obtêm-se o retorno do vetor x após cada iteração i. Do contrário, imprimindo fora do loop obtêm-se apenas o vetor x final.

x <- numeric(0)       # cria um vetor numérico “x” vazio,

for(i in 1:6){        # para: cada elemento "i" na seq. de 1 a 6,
  x[i] <- i*i         # faça: calcule i*i e adicione ao vetor "x",
  print(x)            # imprima = o vetor "x" ao fim de cada iteração,
}                     # fim Para

print(x)              # imprima o vetor "x" final.

Usando os elementos do vetor x para obter \(i^2\), e adicionando os resultados ao vetor y:

x <- c(1, 2, 3, 4)    # cria: um vetor numérico “x” qualquer,
y <- numeric(0)       # cria: um vetor numérico “y” vazio,

for(i in x){          # para: cada elemento "i" em "x",
  y[i] <- x[i]^2      # faça: calcule x[i]^2 e adicione ao vetor "y",
  print(y)            # imprima: o vetor "y" ao fim de cada iteração,
}                     # fim Para

print(y)              # imprima: o vetor "y" final.

O mesmo resultado é alcançado usando-se a função \(\color{magenta}{append()}\) bastando informar os parâmetros x (vetor que receberá os elementos de values) e values (valores que devem ser anexados ao vetor x).

y <- c()                    # cria: um vetor “y” vazio,
for(i in 1:4){              # para: cada elemento "i" na seq. 1:4,
  y <- append(x = y, 
              values = i^2) # faça: calcule i^2 e anexe a "y",
  print(y)                  # imprima: o vetor "y" ao fim de cada iteração,
}                           # fim Para

print(y)                    # imprima: o vetor "y" final.

Condicional \(\color{magenta}{if(~)\color{blue}{\{~\}}}\) dentro do comando \(\color{magenta}{for()}\) - para caso de vetores:

x <- c(10, 9, 15, 16)           # cria: um vetor numérico “x” qualquer,

for(i in x){                    # para: cada elemento "i" em "x",
  if (i == 10){                 # se: "i" for = 10,
    print("É igual a 10")       # imprima: "É igual a 10",
  }else{                        # do contrário,
    print("É diferente de 10")  # imprima: "É diferente de 10",
  }                             # fim Se
}                               # fim Para

Aplicando loops aninhados (consecutivos) com o comando \(\color{magenta}{for()}\). No exemplo, é criada uma matriz a partir do produto de duas sequências: (1,2,3) e (1,2), cujos elementos constituintes são representados por i e j, respectivamente. O resultado do produto é adicionado a uma matriz:

matrix <- matrix(nrow = 3, ncol = 2)

for(i in 1:3){
  for(j in 1:2){
matrix[i,j] = i*j
  }
}
matrix
##      [,1] [,2]
## [1,]    1    2
## [2,]    2    4
## [3,]    3    6

8 Gerando de amostras aleatórias

8.1 Função \(\color{magenta}{\textbf{sample()}}\)

A função \(\color{magenta}{sample(~)}\) permite gerar amostras aleatórias de um determinado vetor ou conjunto de dados, com ou sem reposição dos elementos sorteados. Ao usar a função \(\color{magenta}{sample(~)}\) é necessário usar conjuntamente a função \(\color{magenta}{set.seed(~)}\) para garantir a reprodutibilidade dos números aleatorizados. Caso não seja feito, a cada execução da função um novo conjunto de amostras aleatórias será gerado. Os principais argumentos:

\(\textbf{Sintaxe}\)

\(\color{magenta}{sample(\color{black}{x~=~?,~size~=~?,~replace~=~?,~prob~=~?})}\)

\(\color{black}{\textbf{x}}\) = um vetor de um ou mais elementos de onde deverá ser retirada a amostra ou um inteiro positivo;

\(\color{black}{\textbf{size}}\) = número não negativo e inteiro, referente ao tamanho da amostragem a ser gerada;

\(\color{black}{\textbf{replace}}\) = argumento informando se a amostragem deve ser feita com reposição ou não. O default é FALSE (sem reposição); e

\(\color{black}{\textbf{prob}}\) = vetor de probabilidades para obtenção dos elementos do vetor x que será amostrado. O default é NULL.

Usando a função \(\color{magenta}{sample(~)}\)

1. Gerar uma amostra aleatória de 10 números inteiros, sem reposição, no intervalo de 0 e 100.

set.seed(1)
sample(x=0:100, size=10)
##  [1] 26 37 56 89 19 86 97 62 58  5

2. Gerar uma amostra aleatória de 15 números inteiros, sem reposição, do vetor x.

set.seed(2)
x <- seq(from=1, to=50, by=1)                                                               
sample(x=x, size=15)
##  [1] 10 35 28  8 44 43  6 36 20 23 41 50 29  7 15

3. Gerar uma amostra aleatória de 5 números, com reposição, entre os possíveis resultados de lançamentos de um dado.

set.seed(3)
sample(x=1:6, size=5, replace = TRUE)
## [1] 2 5 3 2 4

4. Gerar uma amostra aleatória de 6 números, sem reposição, entre os possíveis resultados de lançamentos de um dado.

set.seed(4)
sample(x=1:6, size=6, replace = FALSE)
## [1] 4 1 2 5 6 3

5. Gerar uma amostra aleatória, sem reposição, a partir do vetor de caractere de 6 espécies florestais.

set.seed(5)
Especie <- c("Acapu", "Angelim Pedra", "Timborana", "Maparajuba", 
             "Ipê Amarelo", "Jatobá")
sample(x=Especie, size=6, replace = FALSE)
## [1] "Angelim Pedra" "Maparajuba"    "Ipê Amarelo"   "Acapu"        
## [5] "Timborana"     "Jatobá"

6. Gera um erro: quando replace = FALSE, o tamanho da amostra (size) não pode ser maior do que a população em x.

set.seed(6)
Especie <- c("Acapu", "Angelim Pedra", "Timborana", "Maparajuba", 
             "Ipê Amarelo", "Jatobá")
sample(x=Especie, size=7, replace = FALSE)

7. Gerar uma amostra aleatória de 50 diâmetros de árvores, com reposição, do vetor diametro.

set.seed(7)
diametro <- c(23.0, 27.0, 33.6, 42.6, 52.1, 63.2)
sample(x=diametro, size=50, replace = TRUE)
##  [1] 63.2 33.6 23.0 23.0 27.0 52.1 33.6 63.2 23.0 33.6 27.0 27.0 52.1 23.0
## [15] 33.6 23.0 42.6 23.0 63.2 27.0 42.6 27.0 63.2 63.2 63.2 23.0 42.6 33.6
## [29] 63.2 33.6 52.1 27.0 27.0 27.0 33.6 63.2 33.6 52.1 63.2 33.6 52.1 33.6
## [43] 52.1 33.6 63.2 27.0 23.0 52.1 63.2 63.2

8. Gerar uma amostra aleatória dos elementos de um data frame e, em seguida, separa em dados em treino e validação (procedimento comum em aprendizado de máquina).

Para fins didático, usar-se-á o conjunto de dados trees que contém informações de circunferência, altura e volume de 31 árvores de Cerejeira. Assim, a função \(\color{magenta}{sample()}\) será escrita com a seguinte sintaxe:

x = recebe os inteiros que representam os dois conjuntos de dados (1 e 2);

size = recebe o número de linhas (nrow) do conjunto de dados;

replace = TRUE, atribui um 1 ou um 2 a uma determinada linha; e

prob = recebe um vetor de probabilidade (0,7 e 0,3).

Definindo-se replace = TRUE permite-se que a cada novo sorteio atribua-se 1 ou 2 as linhas do data.frame, até que o vetor de probabilidades de 0,7 e 0,3 sejam satisfeitos, ou fiquem próximo do desejado.

set.seed(8)
data("trees")
str(trees)
## 'data.frame':    31 obs. of  3 variables:
##  $ Girth : num  8.3 8.6 8.8 10.5 10.7 10.8 11 11 11.1 11.2 ...
##  $ Height: num  70 65 63 72 81 83 66 75 80 75 ...
##  $ Volume: num  10.3 10.3 10.2 16.4 18.8 19.7 15.6 18.2 22.6 19.9 ...

amostra.aleatoria <- sample(x=1:2, 
                            size=nrow(trees), 
                            replace=TRUE, 
                            prob=c(0.7, 0.3))
amostra.aleatoria
##  [1] 1 1 2 1 1 2 1 2 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 2 1 1 1 2 1
table(amostra.aleatoria)
## amostra.aleatoria
##  1  2 
## 24  7
round(prop.table(table(amostra.aleatoria)), digits = 2)
## amostra.aleatoria
##    1    2 
## 0.77 0.23

Ao imprimir o objeto amostra.aleatoria o sorteio realizado será evidenciado pelos números inteiros (1 e 2) definidos no argumento x. É possível perceber também a ação do argumento prob no processo de amostragem. Cada valor 1 e 2 receberá uma linha do conjunto de dados trees, seguindo a ordem sequencial de sua ocorrência no objeto amostra.aleatoria. Por exemplo, as árvores situadas nas linhas 3, 6, 8, 9, 16, 26 e 3 constituirão o conjunto de valiadação.

which(amostra.aleatoria %in% 1)     #árvores da amostra de treino.
##  [1]  1  2  4  5  7 10 11 12 13 14 15 17 18 19 20 21 22 23 24 25 27 28 29
## [24] 31
which(amostra.aleatoria %in% 2)     #árvores da amostra de validação.
## [1]  3  6  8  9 16 26 30
treino <- trees[amostra.aleatoria==1,] 
str(treino)
## 'data.frame':    24 obs. of  3 variables:
##  $ Girth : num  8.3 8.6 10.5 10.7 11 11.2 11.3 11.4 11.4 11.7 ...
##  $ Height: num  70 65 72 81 66 75 79 76 76 69 ...
##  $ Volume: num  10.3 10.3 16.4 18.8 15.6 19.9 24.2 21 21.4 21.3 ...

validacao <- trees[amostra.aleatoria==2,] 
str(validacao)
## 'data.frame':    7 obs. of  3 variables:
##  $ Girth : num  8.8 10.8 11 11.1 12.9 17.3 18
##  $ Height: num  63 83 75 80 74 81 80
##  $ Volume: num  10.2 19.7 18.2 22.6 22.2 55.4 51

9 Visualização gráfica no R

?par()
## starting httpd help server ... done

9.1 Demonstrativo de gráficos no R

demo(graphics)

9.2 Tipos de comandos: alto ou baixo nível e interativos

9.2.1 Comandos de alto nível (criam gráficos completos)

\(\color{magenta}{plot()}\); \(\color{magenta}{boxplot()}\); e \(\color{magenta}{hist()}\).

9.2.2 Comandos de baixo nível (adicionam informações a algum gráfico já existente)

\(\color{magenta}{points()}\); \(\color{magenta}{lines()}\); e \(\color{magenta}{title()}\).

9.2.3 Comandos interativos (permitem que o usuário interaja com a janela gráfica)

\(\color{magenta}{identify()}\)

9.3 A função \(\color{magenta}{\textbf{plot()}}\)

É uma função genérica para plotagem de objetos R. Para saber mais detalhes sobre os argumentos dos parâmetros gráficos deve-se consulte o par. O uso da função \(\color{magenta}{plot()}\) é um dos mecanismos mais simples para a criação dos gráficos no R. Para estudar alguns detalhes da função \(\color{magenta}{plot()}\) usar-se-á de dados biométricos de 30 árvores de um povoamento de \(\color{red}{\textit{Tectona grandis}}\) situado nas coordenadas geográficas Latitude -03°16’10,96’‘e Longitude -52°23’42,58’’, no Campo Experimental da Embrapa Amazônia Oriental, km 23 da Rodovia BR 230 (Transamazônica), no município de Altamira, Mesorregião do Sudoeste Paraense. O plantio experimental foi conduzido sem tratamentos silviculturais (podas e desbastes), sob o espaçamento 3 x 2 m, perfazendo 3.276 m², com 546 indivíduos, com idades variando entre 5 e 14 anos. O volume do fuste \(\color{red}{\textit{T. grandis}}\) pelo método de Huber.

\(\color{magenta}{plot(\color{black}{x,~y,~type~=~"",~main~=~"",~sub~=~"",~xlab~=~"",~ylab~=~"",~asp~=~""})}\)

teca <- fread("Tectona.csv")
teca
##     Arvore  DAP     H     Volume
##  1:      1  6.6  8.90 0.01659735
##  2:      2  6.8  7.95 0.01667180
##  3:      3  7.0  6.87 0.01418640
##  4:      4  7.1 12.70 0.02669411
##  5:      5  7.5 11.74 0.02845194
##  6:      6  9.9 13.84 0.06552577
##  7:      7 10.8 15.25 0.04901434
##  8:      8 11.2 13.00 0.05769142
##  9:      9 11.3 14.60 0.06561012
## 10:     10 11.7 15.60 0.08286705
## 11:     11 12.6 17.20 0.10011879
## 12:     12 14.0 16.60 0.12726937
## 13:     13 14.3 17.87 0.15799148
## 14:     14 14.6 17.90 0.14122551
## 15:     15 14.9 16.50 0.13180905
## 16:     16 15.0 18.30 0.15302855
## 17:     17 15.3 17.40 0.16190700
## 18:     18 15.4 17.55 0.13909680
## 19:     19 16.2 16.99 0.19180080
## 20:     20 17.1 17.72 0.15774958
## 21:     21 17.4 16.20 0.19560797
## 22:     22 18.0 16.10 0.19684120
## 23:     23 18.1 15.34 0.25018280
## 24:     24 19.2 16.15 0.20325802
## 25:     25 19.8 14.38 0.26157554
## 26:     26 20.6 22.00 0.31693957
## 27:     27 22.5 20.60 0.37742654
## 28:     28 23.5 16.70 0.26324442
## 29:     29 23.8 22.80 0.39531037
## 30:     30 32.6 21.55 0.60309453
##     Arvore  DAP     H     Volume

Pode-se avaliar previamente o conjunto de dados utilizado:

str(teca)      # estrutura do conjunto de dados
## Classes 'data.table' and 'data.frame':   30 obs. of  4 variables:
##  $ Arvore: int  1 2 3 4 5 6 7 8 9 10 ...
##  $ DAP   : num  6.6 6.8 7 7.1 7.5 9.9 10.8 11.2 11.3 11.7 ...
##  $ H     : num  8.9 7.95 6.87 12.7 11.74 ...
##  $ Volume: num  0.0166 0.0167 0.0142 0.0267 0.0285 ...
##  - attr(*, ".internal.selfref")=<externalptr>
summary(teca)  # um rápido sumário estatítico
##      Arvore           DAP              H             Volume       
##  Min.   : 1.00   Min.   : 6.60   Min.   : 6.87   Min.   :0.01419  
##  1st Qu.: 8.25   1st Qu.:11.22   1st Qu.:14.44   1st Qu.:0.06555  
##  Median :15.50   Median :14.95   Median :16.35   Median :0.14713  
##  Mean   :15.50   Mean   :15.16   Mean   :15.88   Mean   :0.16496  
##  3rd Qu.:22.75   3rd Qu.:18.07   3rd Qu.:17.68   3rd Qu.:0.20165  
##  Max.   :30.00   Max.   :32.60   Max.   :22.80   Max.   :0.60309
dim(teca)      # dimensão do conjunto de dados
## [1] 30  4

Criando um gráfico de dispersão entre diâmetro (cm) e altura (m). O default da função \(\color{magenta}{plot()}\) é usar type = p. No entanto outros tipos de plotagem (type) estão disponíveis. O argumento type pode assumir: (p = points, l = lines, b = both, c = lines part alone of b, o = ‘overplotted’, h = ‘histogram’, s = stair steps,S = other steps, n = no plotting).

9.3.1 Modificando o tipo de gráfico (\(\color{blue}{type}\)).

# mar = inferior, esquerda, superior e direita.
par(mar = c(4.5,3.5,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))
plot(teca$DAP,teca$V, main = "type = default")
plot(teca$DAP,teca$V, type="l", main = "type = l")
plot(teca$DAP,teca$V, type="b", main = "type = b")
plot(teca$DAP,teca$V, type="o", main = "type = o")

9.3.2 Adicionando título, subtítulo e rótulos

Usar os comandos \(\color{blue}{main}\) e \(\color{blue}{sub}\) para adicionar um título e subtítulo ao gráfico. Para modificar os títulos dos eixos usar os comandos \(\color{blue}{xlab}\) = Título do eixo x e \(\color{blue}{ylab}\) = Título do eixo y.

par(mar = c(4.5,3.5,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))
plot(teca$DAP,teca$V, type = "o", main = "Relação DAP-Volume")

plot(teca$DAP,teca$V, type = "o", main = "Relação DAP-Volume",
     sub = "(Árvores de Tectona grandis)")

plot(teca$DAP,teca$V, type = "o", main = "Relação DAP-Volume",
     xlab = "DAP (cm)")

plot(teca$DAP,teca$V, type = "o", main = "Relação DAP-Volume",
      xlab = "DAP (cm)", ylab = expression(Volume ~ (m^3)))

O comando \(\color{blue}{title()}\) (comando de baixo nível) constitui outro mecanismo de inserção de título e rótulos de eixos em gráficos da \(\color{magenta}{plot()}\).

par(mar = c(4.5,3.5,1.5,1), mgp = c(2,1,0))

plot(teca$DAP,teca$V, type = "o", xlab = "", ylab = "")

title("Relação DAP-Volume", xlab = "DAP (cm)", ylab = expression(Volume ~ (m^3)))

Se o título for demasiadamente grande pode-se fazer quebra de linha:

par(mar = c(4.5,3.5,1.5,1), mgp = c(2,1,0))

plot(teca$DAP,teca$V, type="o", 
     main="Relação DAP-Volume de árvores de Tectona grandis")

par(mar = c(4.5,4,2.5,1), mgp = c(2,1,0))

plot(teca$DAP,teca$V, type="o", 
     main="Relação DAP-Volume \n (Tectona grandis)",
     xlab = "DAP (cm)", ylab = expression(Volume ~ (m^3)))

9.3.3 Modificando tipos de pontos (\(\color{blue}{\textbf{pch}}\))

Pode-se alterar o tipo de ponto usando o comando \(\color{blue}{pch}\), que recebe um valor numérico que define o tipo de ponto plotado no gráfico.

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(3,2))
plot(teca$DAP,teca$V, pch=0, main = "pch=0")
plot(teca$DAP,teca$V, pch=4, main = "pch=4")
plot(teca$DAP,teca$V, pch=17, main = "pch=17 (triângulo sólido)")
plot(teca$DAP,teca$V, pch="M", main = "pch=M")
plot(teca$DAP,teca$V, pch="T", main = "pch=T")
plot(teca$DAP,teca$V, pch="1", main = "pch=1 (entre aspas)")

9.3.4 Modificando tipos de linhas (\(\color{blue}{\textbf{lty}}\))

Pode-se alterar o tipo de linha usando o comando \(\color{blue}{lty}\), que assume um valor numérico que varia de 0 a 6.

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(3,2))
plot(teca$DAP,teca$V, type="l", main = "default (solid)")
plot(teca$DAP,teca$V, type="l", lty=0, main = "sem linha")
plot(teca$DAP,teca$V, type="l", lty=2, main = "dashed")
plot(teca$DAP,teca$V, type="l", lty=4, main = "dotdash")
plot(teca$DAP,teca$V, type="l", lty=5, main = "longdash")
plot(teca$DAP,teca$V,type="l", lty=6, main = "twodash")

9.3.5 Modificando a largura das linhas (\(\color{blue}{\textbf{lwd}}\))

Pode-se alterar a largura da linha usando o comando \(\color{blue}{lwd}\), que assume sempre um valor numérico positivo maior ou igual a 1.

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))
plot(teca$DAP,teca$V, type="l", lty=2, main = "default")
plot(teca$DAP,teca$V, type="l", lty=2, lwd=2, main = "lwd=2")
plot(teca$DAP,teca$V, type="l", lty=2, lwd=4, main = "lwd=4")
plot(teca$DAP,teca$V, type="l", lty=2, lwd=15, main = "lwd=15")

9.3.6 Modificando cores de pontos e linhas (\(\color{blue}{\textbf{col}}\))

Pode-se alterar a cor das linhas e pontos basta usar o comando \(\color{blue}{col}\) e especificar entre aspas a cor desejada. A função \(\color{magenta}{colors()}\) fornece um variedade de cores disponíveis para uso. Utilize a função \(\color{magenta}{demo(\color{black}{colors)}}\) para visualizar uma demostração de cores.

head(colors(), 40)
##  [1] "white"          "aliceblue"      "antiquewhite"   "antiquewhite1" 
##  [5] "antiquewhite2"  "antiquewhite3"  "antiquewhite4"  "aquamarine"    
##  [9] "aquamarine1"    "aquamarine2"    "aquamarine3"    "aquamarine4"   
## [13] "azure"          "azure1"         "azure2"         "azure3"        
## [17] "azure4"         "beige"          "bisque"         "bisque1"       
## [21] "bisque2"        "bisque3"        "bisque4"        "black"         
## [25] "blanchedalmond" "blue"           "blue1"          "blue2"         
## [29] "blue3"          "blue4"          "blueviolet"     "brown"         
## [33] "brown1"         "brown2"         "brown3"         "brown4"        
## [37] "burlywood"      "burlywood1"     "burlywood2"     "burlywood3"
length(colours())
## [1] 657
par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))
plot(teca$DAP,teca$V, pch=0, col="red", main = "col = red")
plot(teca$DAP,teca$V, pch=15, col="lightblue", main = "col = lightblue")
plot(teca$DAP,teca$V, type="l", lty=2, lwd=4, col="yellow", main = "col = yellow")
plot(teca$DAP,teca$V, type="l", lty=2, lwd=2, col="green3", main = "col = green3")

9.3.7 Modificando cores do título e eixos (\(\color{blue}{\textbf{col.main}}\), \(\color{blue}{\textbf{col.lab}}\) e \(\color{blue}{\textbf{col.axis}}\))

Pode-se alterar as cores do título e labels dos eixos x e y usando os comandos \(\color{blue}{col.main}\) e \(\color{blue}{col.lab}\). O comando \(\color{blue}{col.axis}\) pode ser usado para modificar as cores dos valores dos eixos. Além disso, existem comandos de baixo nível que realizam as mesmas tarefas: \(\color{magenta}{title()}\).

par(mar = c(4.5,3.5,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))
plot(teca$DAP,teca$V, type="o", main="Relação DAP-Volume",
     xlab="DAP (cm)", ylab=expression(Volume ~ (m^3)),
     col.main="red4")

plot(teca$DAP,teca$V, type="o", main="Relação DAP-Volume",
     xlab="DAP (cm)", ylab=expression(Volume ~ (m^3)),
     col.main="red4", col.lab="orange3")

plot(teca$DAP,teca$V, type="o", main="Relação DAP-Volume",
     xlab="DAP (cm)", ylab=expression(Volume ~ (m^3)),
     col.main="red4", col.lab="orange3",
     col.axis="green4")

plot(teca$DAP,teca$V, type="o", xlab="", ylab="")
title("Relação DAP-Volume", col.main="purple",
     xlab="DAP (cm)", ylab=expression(Volume ~ (m^3)), col.lab="green4")

9.3.8 Modificando os limites dos eixos (\(\color{blue}{\textbf{xlim}}\), \(\color{blue}{\textbf{ylim}}\) e \(\color{blue}{\textbf{axis}}\))

Pode-se alterar os limites dos eixos (mínimos e máximos) usando os comandos \(\color{blue}{xlim}\) e \(\color{blue}{ylim}\). Além disso, o comando \(\color{blue}{axis}\) pode ser usado para obter uma maior personalização dos eixos. Porém, no plot original deve constar axes = FALSE.

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(3,2))

plot(teca$DAP,teca$V, pch=0, col="red", 
     xlim=c(0, 40), ylim=c(0, 0.8),
     main="xlim=c(0, 40) e ylim=c(0, 0.8)")

plot(teca$DAP,teca$V, pch=0, col="red", 
     xlim=c(6, 30), ylim=c(0, 0.8),
      main="xlim=c(6, 30) e ylim=c(0, 0.8)")

plot(teca$DAP,teca$V, pch=0, col="red", 
     xlim=c(5, 18), ylim=c(0, 0.5),
     main="xlim=c(5, 18) e ylim=c(0, .5)")

plot(teca$DAP,teca$V, pch=0, col="red", 
     xlim=c(min(teca$DAP), max(teca$DAP)), 
     ylim=c(min(teca$V), max(teca$V)),
     main="xlim=c(min, max) e ylim=c(min, max)")

plot(teca$DAP,teca$V, pch=0, col="red", axes=F)
axis(1, seq(from = round(min(teca$DAP),2), 
            to = round(max(teca$DAP),2), 
            by = 2))
axis(2, seq(from = round(min(teca$V),2), 
            to = round(max(teca$V),2), 
            by = 0.1))

9.3.9 Modificando as bordas dos gráficos (\(\color{blue}{\textbf{bty}}\))

Pode-se alterar o estilo de borda do gráfico usando o comando \(\color{blue}{bty}}\). As opções disponíveis são: bty =“o”, “l”, “7”, “c”, “u”, “]”.

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(4,2))
plot(teca$DAP,teca$V, pch=0, col="red", bty="o", main="bty = o (default")
plot(teca$DAP,teca$V, pch=0, col="red", bty="l", main="bty = l")
plot(teca$DAP,teca$V, pch=0, col="red", bty="7", main="bty = 7")
plot(teca$DAP,teca$V, pch=0, col="red", bty="c", main="bty = c")
plot(teca$DAP,teca$V, pch=0, col="red", bty="u", main="bty = u")
plot(teca$DAP,teca$V, pch=0, col="red", bty="]", main="bty = ]")

plot(teca$DAP,teca$V, pch=0, col="red", main="Função = box()")
box(which="plot", lty=2, bty ="l", lwd=5)

9.3.10 Modificando o comprimento e a direção dos marcadores de eixos (\(\color{blue}{\textbf{tcl}}\))

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))
plot(teca$DAP,teca$V, pch=0, main="tcl=-0.5 (default)")
plot(teca$DAP,teca$V, pch=0, tcl=0.4, main="tcl=0.4")
plot(teca$DAP,teca$V, pch=0, tcl=0.01, main="tcl=0.01")
plot(teca$DAP,teca$V, pch=0, tcl=-1, main="tcl=-1")

9.3.11 Modificando a orientação dos valores nos eixos (\(\color{blue}{\textbf{las}}\))

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))
plot(teca$DAP,teca$V, pch=0, las=0, main="paralelos aos eixos")
plot(teca$DAP,teca$V, pch=0, las=1, main="sempre horizontais")
plot(teca$DAP,teca$V, pch=0, las=2, main="perpendiculares aos eixos")
plot(teca$DAP,teca$V, pch=0, las=3, main="sempre verticais")

9.3.12 Modificando o tamanho dos pontos (\(\color{blue}{\textbf{cex}}\))

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))
plot(teca$DAP,teca$V, pch=0,  main="cex = 1 (default)")
plot(teca$DAP,teca$V, pch=0, cex=0.5, main="cex = 0.5")
plot(teca$DAP,teca$V, pch=0, cex=1.5, main="cex = 1.5")
plot(teca$DAP,teca$V, pch=0, cex=3, main="cex = 3")

9.3.13 Modificando o tamanho do título, valores e labels dos eixos (\(\color{blue}{\textbf{cex.main}}\), \(\color{blue}{\textbf{cex.axis}}\) e \(\color{blue}{\textbf{cex.lab}}\))

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(4,2))

plot(teca$DAP,teca$V, pch=0, main="default")

plot(teca$DAP,teca$V, pch=0, main="Relação DAP-Volume",cex.main=1.5)
plot(teca$DAP,teca$V, pch=0, main="Relação DAP-Volume",cex.main=2)

plot(teca$DAP,teca$V, pch=0, cex.axis=.5, main="cex.axis = .5")
plot(teca$DAP,teca$V, pch=0, cex.axis=1.5, main="cex.axis = 1.5")

plot(teca$DAP,teca$V, pch=0, xlab="DAP (cm)",cex.lab=.5, main="cex.lab = .5")
plot(teca$DAP,teca$V, pch=0, xlab="DAP (cm)",cex.lab=1.5, main="cex.lab = 1.5")

plot(teca$DAP,teca$V, pch=0, xlab="")
title(main="Relação DAP-Volume", cex.main=2, xlab="DAP (cm)", cex.lab=1.5)

9.4 A função \(\color{magenta}{\textbf{hist()}}\)

A função genérica \(\color{magenta}{hist()}\) calcula um histograma para os valores de dados fornecidos. Caso a especificação seja plot = TRUE (default), um histograma é plotado. Do contrário, se plot = FALSE a função apenas calcula internamente todos os parâmetros de \(\color{magenta}{hist()}\). Você pode acessar os argumentos da função fazendo: ?hist ou ?plot.histogram. Os principais comandos da função \(\color{magenta}{hist()}\):

\(\textbf{Sintaxe}\)

\(\color{magenta}{hist(\color{black}{x,~breaks~=~"Sturges",~nrow,~freq~=~NULL,~include.lowest~=~TRUE,~right~=~TRUE,~col~=~NULL,~border~=~NULL,~main~=~"Histogram of",~xlim~=~range(breaks),~ylim~=~NULL,~xlab,~ylab,~axes~=~TRUE,~right~=~TRUE})}\)

Onde:

\(\color{black}{\textbf{x}}\) = conjunto de dados;

\(\color{black}{\textbf{breaks}}\) = define os intervalos da classe - pode ser uma função, vetor, número;

\(\color{black}{\textbf{freq}}\) = Se TRUE = frequência (contagem), FALSE = densidade (probabilidade);

\(\color{black}{\textbf{include.lowest}}\) = Incluir o menor valor no intervalo definido pelo break;

\(\color{black}{\textbf{col e border}}\) = Cores das barras e das bordas;

\(\color{black}{\textbf{main}}\) = Título do gráfico;

\(\color{black}{\textbf{xlim e ylim}}\) = Limites dos eixos;

\(\color{black}{\textbf{xlab e ylab}}\) = Título dos eixos;

\(\color{black}{\textbf{axes}}\) = Se axes = TRUE os eixos são desenhados; e

\(\color{black}{\textbf{right}}\) = Se right = TRUE intervalo aberto a esquerda.

hist(teca$DAP, main="default")
rug(teca$DAP)

9.4.1 Modificando o intervalo das classes

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))

hist(teca$DAP, right = TRUE);rug(teca$DAP)
hist(teca$DAP, right = FALSE); rug(teca$DAP)     #Intervalo aberto a direita

x <- c(2,2,2,3,4,4,5,6,7,7,7,8)

hist(x, right=TRUE)
hist(x, right=FALSE)

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))

hist(x, right = TRUE, 
     include.lowest = TRUE)

# Mensagem de aviso, pois falta o argumento breaks
hist(x, right = TRUE, 
     include.lowest = FALSE)         
## Warning in hist.default(x, right = TRUE, include.lowest = FALSE):
## 'include.lowest' ignored as 'breaks' is not a vector
hist(x, right = TRUE, 
     include.lowest = FALSE,
     breaks=1:8)                    # Intervalo entre as classes

9.4.2 Modificando os breaks

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(1,2))

hist(teca$DAP, col="red4", probability = TRUE)

hist(teca$DAP, col="red4", probability = TRUE,
     breaks = c(c(0,5), c(5,10), c(10,15), c(15,20), c(20,25), c(25,30), c(30,35)),
     ylim=c(0,0.06))

9.4.3 Parâmetros do histograma

hist <- hist(teca$DAP)

hist$breaks               # breakpoints (Regra de Sturges).
## [1]  5 10 15 20 25 30 35
hist$counts               # frequência absoluta em cada classe.
## [1]  6 10  9  4  0  1
hist$mids                 # ponto médio das classes.
## [1]  7.5 12.5 17.5 22.5 27.5 32.5
hist$density      
## [1] 0.040000000 0.066666667 0.060000000 0.026666667 0.000000000 0.006666667

9.4.4 Modificando as cores das colunas e bordas (\(\color{blue}{\textbf{col}}\) e \(\color{blue}{\textbf{border}}\))

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))

hist(teca$DAP, col="red4")
hist(teca$DAP, col="green")

hist(teca$DAP, col="red4")
hist(teca$DAP, col="red4", border="blue")

9.4.5 Mostrando as probabilidades (\(\color{blue}{\textbf{density}}\))

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(1,2))
hist(teca$DAP)
hist(teca$DAP, probability = TRUE)             # density = 0 a 1

9.4.6 Número de classes (\(\color{blue}{\textbf{nc}}\))

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))

hist(teca$DAP, main = "nc = Sturges")
hist(teca$DAP, nc = 10, main = "nc = 10")
hist(teca$DAP, nc = 6, main = "nc = 6")
hist(teca$DAP, nc = 3, main = "nc = 3")

9.5 A função \(\color{magenta}{\textbf{pie()}}\) (setores)

A função genérica \(\color{magenta}{pie()}\) pode ser usada para construir um gráfico de setores. Para saber os principais argumentos da função faça ?pie.

\(\textbf{Sintaxe}\)

\(\color{black}{\textbf{labels}}\) = vetor contendo os rótulos de cada fatia;

\(\color{black}{\textbf{radius}}\) = raio da circunferência do gráfico (default=1); e

\(\color{black}{\textbf{col}}\) = vetor contendo as cores de cada fatia.

Construindo uma gráfico de setores a partir de um data frame com as contagens já disponíveis:

par(mar = c(1,3,1,1), mgp = c(1,1,0))
df <- data.frame(
  especie = c("Araucaria", "Acapu", "Mogno", "Ipe"),
  contagem = c(15, 30, 10, 20))
print(df)
##     especie contagem
## 1 Araucaria       15
## 2     Acapu       30
## 3     Mogno       10
## 4       Ipe       20
pie(df$contagem, labels = df$especie, main="")

9.5.1 Usando a função \(\color{magenta}{\textbf{table()}}\)

Para obter contagens de fatores pode-se usar a função \(\color{magenta}{table()}\). Vamos obter uma tabela de contagem para o data set iris. Quantas flores existem de cada espécie (setosa, virginica e versicolor)?

par(mar = c(1,3,1,1), mgp = c(1,1,0))
head(iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa
table(iris$Species)
## 
##     setosa versicolor  virginica 
##         50         50         50
pie(table(iris$Species))

9.5.2 Modificando cores (\(\color{blue}{\textbf{col}}\))

Um esquema de cores

par(mar = c(1,3,1,1), mgp = c(1,1,0))
pie(rep(1, 24), col = rainbow(24), radius = 1)

Modificando a cor das fatias

par(mar = c(1,3,1,1), mgp = c(1,1,0), mfrow = c(1,2))

pie(table(iris$Species),col = c("purple", "violetred1", "green3"))
    
pie(table(iris$Species),col = gray(seq(0.4, 1.0, length = 6)))

9.5.3 Modificando o sentido do desenho das fatias (horário e anti-horário)

par(mar = c(1,3,1,1), mgp = c(1,1,0), mfrow = c(1,2))

pie(table(iris$Species),
    col = c("purple", "violetred1", "green3"),
    clockwise = TRUE)

pie(table(iris$Species),
    col = c("purple", "violetred1", "green3"),
    clockwise = FALSE)

9.5.4 Modificando o tamanho do gráfico (\(\color{blue}{\textbf{radius}}\))

par(mar = c(1,3,1,1), mgp = c(1,1,0), mfrow = c(2,2))

pie(table(iris$Species), radius=0.3,
    col = c("purple", "violetred1", "green3"),
    main = "radius=0.3")

pie(table(iris$Species), radius=0.5,
    col = c("purple", "violetred1", "green3"),
    main = "radius=0.5")

pie(table(iris$Species), radius=0.7,
    col = c("purple", "violetred1", "green3"),
    main = "radius=0.7")

pie(table(iris$Species), radius=1,
    col = c("purple", "violetred1", "green3"),
    main = "radius=1")

9.6 A função \(\color{magenta}{\textbf{boxplot()}}\)

A função \(\color{magenta}{boxplot()}\) pode ser usada para obter um gráfico de boxplot.

9.6.1 Criando um boxplot

par(mar = c(2,3,1.5,1), mgp = c(2,1,0), mfrow = c(1,2))
?boxplot
boxplot(Sepal.Width~Species, data=iris)
boxplot(Petal.Width~Species, data=iris)

9.6.2 Modificando as cores das caixas (\(\color{blue}{\textbf{col}}\))

par(mar = c(2,3,1.5,1), mgp = c(2,1,0))
boxplot(Sepal.Width~Species, data=iris, col=c("red4", "green","blue"))

9.6.3 Plotando os outliers (\(\color{blue}{\textbf{outline}}\))

par(mar = c(2,3,1.5,1), mgp = c(2,1,0), mfrow = c(1,2))

boxplot(Petal.Length~Species, data=iris, 
        col=c("red4", "green","blue"), outline=TRUE)

boxplot(Petal.Length~Species, data=iris, 
        col=c("red4", "green","blue"), outline=FALSE)

9.6.4 Alterando a orientação (\(\color{blue}{\textbf{horizontal}}\))

par(mar = c(2,3,1.5,1), mgp = c(2,1,0), mfrow = c(1,2))

boxplot(Petal.Length~Species, data=iris, 
        col=c("red4", "green","blue"),
        outline=FALSE, horizontal=FALSE)

boxplot(Petal.Length~Species, data=iris, 
        col=c("red4", "green","blue"), 
        outline=FALSE, horizontal=TRUE)

9.6.5 Inserindo a variação dentro da caixa do boxplot (\(\color{blue}{\textbf{varwidth}}\))

par(mar = c(2,3,1.5,1), mgp = c(2,1,0), mfrow = c(1,2))

boxplot(Sepal.Width~Species, data=iris, 
        col=c("red4", "green","blue"), 
        outline=TRUE, varwidth=FALSE)

boxplot(Sepal.Width~Species, data=iris, 
        col=c("red4", "green","blue"), 
        outline=TRUE, varwidth=TRUE)

9.7 Adicionando elementos a um gráfico existente

9.7.1 Adcionando pontos (\(\color{magenta}{\textbf{points()}}\))

par(mar = c(2,3,1.5,1), mgp = c(2,1,0))
plot(teca$DAP,teca$V, pch=19)
points(rev(teca$DAP), teca$V, col="red", pch=10) # Reverso da variável DAP com o V

9.7.2 Adicionando linhas (\(\color{magenta}{\textbf{lines()}}\))

O comando \(\color{magenta}{lines()}\) é muito usado para adicionar a linha de ajuste de regressão linear simples.

par(mar = c(2,3,1.5,1), mgp = c(2,1,0))
plot(teca$DAP,teca$V, pch=19)
lines(teca$DAP, teca$V*1.5, col="red4")
lines(teca$DAP, teca$V/2, col="blue")

9.7.3 Adicionando retas (\(\color{magenta}{\textbf{ablines()}}\))

par(mar = c(2,3,1.5,1), mgp = c(2,1,0))
plot(teca$DAP,teca$V, pch=19)

# x = intercepto e y = beta 1
abline(lm(teca$V ~ teca$DAP)$coefficients[1],
       lm(teca$V ~ teca$DAP)$coefficients[2], 
       col="red", lwd=2, lty=1) 

abline(h=.4, col="red4")

# Reta horizontal passando por y=200 na cor vermelha
abline(h=.2, col="red4", lwd=4)   

# Reta vertical passando por x=10 na cor amarela, 
# do tipo pontilhada e com largura de 5
abline(v=10, col="yellow", lty=3, lwd=5) 

# Ficou na frente da linha anterior
abline(v=10, col="red", lty=3, lwd=1) 

9.7.4 Adicionando texto (\(\color{magenta}{\textbf{text()}}\))

par(mar = c(2,3,1.5,1), mgp = c(2,1,0))
plot(teca$DAP,teca$V, pch=19)
text(10,0.6, "Tectona grandis")
text(16,0.5, "R para floresta")

9.7.5 Múltiplos gráficos na mesma janela

# Duas linhas e duas colunas
op <- par(mar = c(4.5,3,1,1), mgp = c(2,1,0), mfrow = c(2,2))      
plot(teca$DAP,teca$V, pch=14, col="green")
plot(teca$DAP,teca$V, type="l", lty=5, lwd=4)
boxplot(Sepal.Length~Species, data=iris, col="blue4")
hist(teca$H, nc=5, col="orange")

par(op)
plot(teca$DAP,teca$H, pch=14)

Configurando as margens

# Margens - mar(bottom, left, top, right)
op <- par(mfrow=c(2,2), mar = c(4.5,3,1,1))
plot(teca$DAP,teca$V, pch=14)
plot(teca$DAP,teca$V, pch=20)
plot(teca$DAP,teca$V,type="l", lty=2, col="blue4")
hist(teca$DAP, nc=5)

10 Análise exploratória de dados

10.1 Configurando diretório de trabalho (\(\color{magenta}{\textbf{getwd()}}\) e \(\color{magenta}{\textbf{setwd()}}\))

Um detalhe importante no início de cada seção de trabalho no R é inspecionar o seu diretório de trabalho atual, isto é, o local onde serão salvos os arquivos produzidos pelo R (.R, etc.). Para tanto, basta usar a função \(\color{magenta}{getwd()}\). Caso não esteja no diretório desejado use a função \(\color{magenta}{setwd(\color{blue}{choose.dir()})}\) para selecioná-lo. A função \(\color{magenta}{dir()}\) é usada para listar os arquivos existentes no diretório corrente.

getwd()
setwd(choose.dir())
dir()

10.2 Importando um conjunto de dados

10.2.1 Funções \(\color{magenta}{\textbf{read.csv()}}\) e \(\color{magenta}{\textbf{read.table()}}\)

O R permite importar dados disponíveis em outros formatos, por exemplo, .csv (Comma-separated values) ou .txt (arquivo de texto). Ainda, é possível importar os dados de arquivos de outros programas estatísticos (SPSS, SAS, Stata). Duas funções extremamente úteis para realizar essa tarefa são \(\color{magenta}{read.csv()}\) (importa arquivos no formato .csv) e \(\color{magenta}{read.table()}\) (importar arquivos no formato .txt). Se os dados estiverem em planilha do Microsoft Excel, pode-se salvá-los com a extensão .txt fazendo: salvar como → texto (separado por tabulações) (*.txt)..

A função \(\color{magenta}{read.table()}\) possui diversos argumentos que devem ser cuidadosamente compreendidos. Alguns dos argumentos mais importantes são tratados:

\(\color{magenta}{read.table(\color{black}{file,header=T,sep=";",quote = "\",dec = ".",as.is = !stringsAsFactors,na.strings=c("NA","","NULL",)encoding = "unknown"})}\)

Onde:

\(\color{black}{\textbf{file}}\) = nome do arquivo que contém o conjunto de dados;

\(\color{black}{\textbf{header}}\) = um valor lógico indicando se o arquivo contém os nomes das variáveis na primeira linha. Se header = TRUE informa que contém nomes;

\(\color{black}{\textbf{quote}}\) = define células de texto. O default é interpretar tanto aspa simples como dupla presentes;

\(\color{black}{\textbf{sep}}\) = separador de colunas usado no arquivo. O default é espaço;

\(\color{black}{\textbf{dec}}\) = separador decimal usado no arquivo. O default é ponto (.);

\(\color{black}{\textbf{as.is}}\) = o padrão da \(\color{magenta}{read.table()}\) é converter variáveis de caracteres em fatores. Usar TRUE não fara a conversão;

\(\color{black}{\textbf{na.strings}}\) = se definir, pode informar que símbolos em células inteiras sejam interpretados como valores ausentes (NA); e

\(\color{black}{\textbf{encoding}}\) = codificação da acentuação. O deafult é unknown (desconhecido), na qual ele reconhece segundo o sistema operacional. As opções mais usadas são Latin- ou UTF-8.

Os dados importados são coagidos a um data frame. Para usar as funções deve-se informar o caminho completo do arquivo. Para entender os argumentos da função \(\color{magenta}{read.table()}\), importar-se-á o arquivo nomeado arvores.txt que deve estar no diretório corrente, e atribuir-se-á o nome nativas ao objeto.

Do arquivo original arvores.txt têm-se os seguintes formatos:

  • As colunas estão separadas por tabulação (no R isso é definido pela expressão regular \(\t\));
  • O separador decimal usado no arquivo é ponto (.);
  • Não tem aspas definindo as colunas de texto; e
  • O arquivo contém os nomes das variáveis na primeira linha.

O que aconteceria se especificasse errôneamente o separador de colunas usado no arquivo, cujo default é espaço? No exemplo, usa-se o separador vírgula (,) para fins de exemplificação. Fazendo isso, as duas colunas existentes são interpretadas como uma só.

nativas <- read.table(file = "arvores.txt", sep=",", header=T)
dim(nativas) # apenas 1 coluna, porque o separador não está correto.
## [1] 25  1

Então, para ler o arquivo arvores.txt corretamente deve-se fazer:

nativas <- read.table("arvores.txt", header = T, sep="")

nativas                               # Imprime o data frame
##    Arvores Altura
## 1        1   18.0
## 2        2   15.0
## 3        3   19.0
## 4        4   12.0
## 5        5   14.0
## 6        6   14.0
## 7        7   17.0
## 8        8   21.0
## 9        9   20.5
## 10      10   23.0
## 11      11   19.0
## 12      12   21.0
## 13      13   18.0
## 14      14   16.0
## 15      15   12.0
## 16      16   14.0
## 17      17   15.5
## 18      18   19.5
## 19      19   22.0
## 20      20   20.3
## 21      21   24.0
## 22      22   17.0
## 23      23   14.0
## 24      24   18.0
## 25      25   21.0
summary(nativas)                      # Resumo estatítico dos dados
##     Arvores       Altura     
##  Min.   : 1   Min.   :12.00  
##  1st Qu.: 7   1st Qu.:15.00  
##  Median :13   Median :18.00  
##  Mean   :13   Mean   :17.79  
##  3rd Qu.:19   3rd Qu.:20.50  
##  Max.   :25   Max.   :24.00
class(nativas)                        # um data.frame
## [1] "data.frame"
dim(nativas)                          # dimensão do objeto
## [1] 25  2
head(nativas)                         # 6 primeiros dados
##   Arvores Altura
## 1       1     18
## 2       2     15
## 3       3     19
## 4       4     12
## 5       5     14
## 6       6     14
nativas[nrow(nativas),]               # última linha
##    Arvores Altura
## 25      25     21

Um aspecto importante na análise exploratória é verificar se o conjunto de dados possui valores faltantes. Para tanto, pode-se usar a função lógica \(\color{magenta}{is.na()}\):

is.na(nativas)

10.2.2 Função \(\color{magenta}{\textbf{read.xlsx()}}\)

Existem diversos pacotes com funções dedicadas à importação de conjuntos de dados para o ambiente R. Um exemplo é o pacote xlsx (DRAGULESCU, 2014) desenvolvido para permitir a leitura de dados diretamente de planilhas do Microsoft Excel usando a função \(\color{magenta}{read.xlsx()}\). O Microsoft Excel permite salvar arquivos tanto no formato xls (versões até 2003) quanto no formato xlsx (versões anteriores). Inicialmente é preciso realizar a instalação: \(\color{magenta}{install.packages(\color{black}{xlsx})}\). Em seguida, usar-se-á a função para importar o arquivo guanandi.xlsx que contém quatro variáveis (muda, dcolo, h (altura) e folhas).

library(xlsx)                    # Carrega o pacote

# Usando read.xlsx(): sheetName = Nome arquivo
guanandi <- read.xlsx(file = "guanandi.xlsx",
                     sheetName = "guanandi", head = TRUE)

guanandi
##    muda dcolo    h folhas
## 1     1   1.7 20.0      6
## 2     2   2.4 18.0      9
## 3     3   3.5 17.5     10
## 4     4   3.0 17.0     11
## 5     5   3.2 19.5      4
## 6     6   2.9 20.1      5
## 7     7   1.4 19.0      6
## 8     8   0.9 20.2      7
## 9     9   3.1 18.6      9
## 10   10   3.6 17.4     10
## 11   11   2.2 16.0      8
## 12   12   1.4 17.9     11
## 13   13   1.6 18.1     12
## 14   14   1.0 19.0      6
## 15   15   2.8 21.0      4
## 16   16   1.6 20.6      9
## 17   17   1.9 22.0      8
## 18   18   2.3 17.4     11
## 19   19   2.7 16.9     10
## 20   20   3.0 16.3     10
## 21   21   3.1 19.5      5
## 22   22   2.7 18.4      7
## 23   23   1.9 20.6      9
## 24   24   2.2 21.1     10
## 25   25   3.0 20.0      9

10.3 Estatística descritiva

Estatística descritiva é a parte da estatística que descreve e avalia um conjunto de dados, sejam populacionais ou oriundos de uma amostra representativa da população. Em termos gerais, dispõe-se de dados amostrais. O simples uso de estatísticas descritivas não nos permite conclusões e/ou inferências robustas sobre uma determinada população. No entanto, nos fornece informações iniciais relevantes sobre a estrutura dos dados, e auxilia nas tomadas de decisões sobre tratamentos e métodos estatísticos adequados. Em estatítica descritiva, em geral, existem dois métodos comuns de representar os dados: a) método gráfico (gráficos e tabelas); e b) método numérico (medidas de tendência central, dispersão, entre outros). As medidas de tendência central incluem: média aritmética, moda, mediana, entre outras. As medidas de dispersão incluem: amplitude total, variância, desvio padrão e coeficiente de variação.

10.3.1 Medidas de tendência central

1. Média aritmética: Matematicamente é a soma de todos os elementos de uma amostra ou população dividida pela quantidade de elementos. A média aritmética é a medida de tendência central mais conhecida e pode ser facilmente obtida no R usando a função \(\color{magenta}{mean()}\):

\[ \bar{x} = \frac{1}{n} \sum_{i=1}^n X_i \]

x <- c(1, 5, 7, 18, 32, 10, 6)               # criando um vetor
mean(x)                                      # obtendo a média
## [1] 11.28571

Em algumas situações é possível que haja no conjunto de dados valores ausentes (NA). Nesses casos, deve-se usar argumento na.rm = TRUE para que o cálculo da média seja realizado desconsiderando o valor desconhecido NA.

w <- 1:5
w[2] <- NA
print(w)
## [1]  1 NA  3  4  5

mean(w)                                # cálculo inapropriado
## [1] NA

mean(w, na.rm = TRUE)                  # cálculo apropriado
## [1] 3.25

2. Mediana: É um valor intermediário de um conjunto de dados, cujos n valores são dispostos ordenadamente (rank). De outro modo, é valor que divide um conjunto de dados em duas partes iguais em que 50% dos dados ordenados estão acima da mediana e 50% estão abaixo da mediana. O uso da médiana é indicado quando o conjunto de dados possui valores extremos (outliers), pois o uso da média pode ser viesado. Existem duas regras básicas para descobrir a posição da mediana nos dados ordenados, a partir do número de observações (n) do conjunto de dados:

  • Se n for ímpar: a mediana será o valor que ocupa a posição: (n+1)/2
  • Se n for par: a mediana será a média aritmética dos valores que ocupam as posições: n/2 e n/2+1

O ambiente R possui a função \(\color{magenta}{median()}\) que calcula a mediana de um conjunto de dados, sem a necessidade de realizar o procedimento de ordenamento para encontrar a posição da medida e, assim obter seu valor.

x <- c(1, 5, 7, 18, 32, 10, 6)           # vetor não ordenado (n=7)
y <- c(1, 5, 6, 7, 10, 18, 32)           # vetor ordenado (n=7)

median(x)                                # a mediana?
## [1] 7
median(y)                                # a mediana?
## [1] 7

3. Moda: Refre-se ao valor mais frequente dentro do conjunto de dados. Um conjunto de dados pode ser classificado quanto à moda em: a) amodal; b) unimodal; c) bimodal; e d) multimodal. Um conjunto de dados é dito amodal quando não possui moda. Isto ocorre quando não existe um valor mais frequente. Unimodal quando possui apenas uma moda (um valor mais frequente). Bimodal quando possui duas modas. Multimodal quando possui três ou mais modas. Por não ser uma medida de posição muito usual no R-base não existe uma função específica para calcular a moda. Então, para obter a moda utilizar-se-á do pacote modeest (PONCET, 2012) que dispões a função \(\color{magenta}{mfv}\) (Most frequent value). No entanto, a função \(\color{magenta}{mfv}\) recebe apenas um vetor numérico. Quando deseja-se saber o moda para um vetor de character (variável nominal) pode-se usar a função \(\color{magenta}{modeOf()}\) do pacote lsr (NAVARRO, 2015). Ao contrário da função \(\color{magenta}{mfv}\), a função \(\color{magenta}{modeOf()}\) funciona para vetores numéricos e caracteres.

library(modeest)
v <- seq(from = 1, to = 10, by = 1)                 # amodal (todos valores)
x <- c(0, 1, 2, 3, 4, 5, 5, 5, 5, 6, 6, 7, 7, 8)    # unimodal
y <- c(0, 1, 2, 3, 4, 5, 5, 5, 6, 6, 7, 7, 7)       # bimodal
z <- c(0, 1, 2, 3, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7)    # multimodal
mfv(v)
##  [1]  1  2  3  4  5  6  7  8  9 10
mfv(x)
## [1] 5
mfv(y)
## [1] 5 7
mfv(z)
## [1] 5 6 7

Outra forma interessante de obter a moda é usar a função \(\color{magenta}{table()}\) já apresentada na construção de gráficos de setores.

x <- c(0, 1, 2, 3, 4, 5, 5, 5, 5, 6, 6, 7, 7, 8) 
table(x)
## x
## 0 1 2 3 4 5 6 7 8 
## 1 1 1 1 1 4 2 2 1

Veja uma situação para um vetor de caracteres (variável nominal):

library(lsr)
especie <- c(rep("Araucaria", 20), rep("Acapu", 10), 
             rep("Mogno", 5), rep("Ipe", 2))
class(especie)
## [1] "character"
modeOf(especie)
## [1] "Araucaria"
table(especie)
## especie
##     Acapu Araucaria       Ipe     Mogno 
##        10        20         2         5

Para finalizar, agora um exemplo com todas as medidas de tendência central:

x <- c(20,7,5,9,6,21,24,10,12,22,21,16,13,6,6,2,19,3,10,7,2,18,4,6,18)
mean(x)                                  # obtendo a média
## [1] 11.48

median(x)                                # obtendo a mediana
## [1] 10

mfv(x)                                   # obtendo a moda (pacote modeest)
## [1] 6

table(x)                                 # frequências de cada valor
## x
##  2  3  4  5  6  7  9 10 12 13 16 18 19 20 21 22 24 
##  2  1  1  1  4  2  1  2  1  1  1  2  1  1  2  1  1

10.3.2 Medidas de dispersão

As medidas de dispersão: são medidas descrevem a variabilidade existente em umdeterminado conjunto de dados. As medidas de dispersão incluem: amplitude total, variância, desvio padrão e coeficiente de variação.

1. Amplitude total: Refere-se a diferença entre o maior (máximo) e o menor (mínimo) valor de um conjunto de dados. A AT é uma medida grosseira de existência de variabilidade, não sendo robusta para medir variabilidade de um conjunto de dados por utilizar-se apenas dos valores extremos na distibuição amostral. No entanto, serve para indicar se existe ou não dispersão no conjunto. No ambiente R pode-se obter a amplitude total através de modo indireto (AT = máximo - mínimo). Porém, existe a função \(\color{magenta}{range()}\) que retorna os valores mínimos e máximos, permitindo, em seguida o cálculo da AT.

t <- c(2, 4, 5, 6, 10)

max(t)-min(t)                # indiretamente
## [1] 8
range(t)                     # mostra o min(t) e o max(t)
## [1]  2 10
range(t)[2]-range(t)[1]      # outra maneira
## [1] 8

2. Variância: A variância amostral é uma medida de dispersão ou variabilidade dos dados que, mais comumente, é calculada relativamente à localização média. No ambiente R pode-se usar a função \(\color{magenta}{var()}\) para calcular a variância. A variância amostral é dada por:

\[ \mbox{s²} = \frac{1}{n-1} \sum_{i=1}^n \left( x_i - \bar{x} \right)^2 \]

z <- c(1, 2, 3, 4, 5)
var(z)
## [1] 2.5

Para treinar os outros recursos do ambiente R, realize o seguinte comando (a partir da fórmula da variância amostral):

#Soma de Quadrados dos Desvios, dividido pelo graus de liberdade (n-1)
sum((z-mean(z))^2)/(length(z)-1)
## [1] 2.5

3. Desvio Padrão: definido como a raiz quadrada positiva da variância. O uso do desvio-padrão tem grande vantagem sobre a variância, já que é apresentado na mesma unidade de medida dos dados brutos. No ambiente R pode-se usar a função \(\color{magenta}{sd()}\) (standard deviation) para calcular o desvio padrão ou simplesmente obter a raiz quadrada da variância. O desvio padrão amostral é dado por:

\[ s = \sqrt{ \frac{1}{n-1} \sum_{i=1}^n \left( x_i - \bar{x} \right)^2 } \]

x <- c(1, 2, 3, 4, 5)

sqrt(var(x))                       # é a raiz quadrada da variância
## [1] 1.581139
sd(x)                              # ou usar sd()
## [1] 1.581139

4. Coeficiente de variação: Uma medida relativa da dispersão. Obtida em função do desvio padrão e média aritmética amostral. No R-base não existe uma função específica para calcular o CV. Porém, pode ser obtido facilmente dividindo o desvio padrão pela média aritmética amostral (desvio padrão/média), em seguida multiplica-se por 100, para obter a medida em percentual (%). Ainda, pode-se usar a função \(\color{magenta}{coefficient.variation()}\) do pacote FinCal (FAN, 2016).

library(FinCal)
z <- c(1, 2, 3, 4, 5)

sd(z)/mean(z)*100                               # desvio padrao/média
## [1] 52.70463

coefficient.variation(sd=sd(z),avg=mean(z))*100 # usar a função
## [1] 52.70463

Outras medidas de dispersão também podem ser calculada, como é o caso do erro-padrão da média: O Erro-padrão mede a precisão da média. A fórmula é: desvio padrão/raiz(n) ou raiz quadrada(variância/n). Médias com menor erro-padrão são consideradas mais precisas.

10.3.3 Exercício prático: análise descritiva

Para aprimorar o conhecimento da parte descritiva básica utilizar-se-á o data set iris. Inicialmente, use as funções do R-base detalhadas anteriormente e, somente depois use o pacote fBasics para obter as estatísticas descritivas para cada variável do data set iris. Responda as questões a seguir:

a) Qual a média aritmética das variáveis Sepal.Length, Sepal.Width, Petal.Length e Petal.Width?

b) Qual a medina das variáveis Sepal.Length, Sepal.Width, Petal.Length e Petal.Width?

c) Qual a moda das variáveis Sepal.Length, Sepal.Width, Petal.Length, Petal.Width e Species?

d) Qual a amplitude total das variáveis Sepal.Length, Sepal.Width, Petal.Length, Petal.Width?

e) Qual a variância amostral das variáveis Sepal.Length, Sepal.Width, Petal.Length, Petal.Width?

f) Qual o desvio padrão amostral das variáveis Sepal.Length, Sepal.Width, Petal.Length, Petal.Width?

g) Qual o coeficiente de variação das variáveis Sepal.Length, Sepal.Width, Petal.Length, Petal.Width?

h) Use o pacote fBasics e obtenha as estatísticas descritivas para cada variáveis do data set iris.

11 Testes estatísticos básicos

Ao tratarmos da análise de experimentos, é necessária a realização de testes estatísticos para verificação de determinadas hipóteses. Teste de hipóteses referem-se ao estabelecimento de uma regra decisória que permite rejeitar ou não uma hipóese estatística com base nos elementos amostrais (LEHMANN; ROMANO, 2005). Região crítica de rejeição (maioria dos testes considera 95% de probabilidade).

Atualmente, ao invés de fixar o nível de significância de um teste e simplesmente relatar se \(H_0\) foi rejeitada ou não, tem-se dado preferência ao uso do valor de p. Assim, a hipótese de nulidade (\(H_0\)) é rejeitada se o valor de \(p\) for menor ou igual à \(\alpha\) (alfa). Então, para aplicação de um teste de hipótese os procedimento geral seria:

  1. Formular as hipóteses \(H_0\) e \(H_1\) (hipótese do experimento) e definir o nível de significância (\(\alpha\));
  2. Especificar a estatística do teste;
  3. Determinar o valor da estatística do teste e valor de p correspondente; e
  4. Comparar o \(p\)-valor com \(\alpha\) (alfa).
  • Se \(p\)-valor for menor ou igual a \(\alpha\), rejeita-se \(H_0\).
  • Se \(p\)-valor for maior do que \(\alpha\), não rejeita-se \(H_0\).

11.1 Teste \(t\)-Student:

Teste de hipótese utilizado em várias situações de pesquisa quando se deseja, por exemplo, testar uma afirmação sobre a média populacional ou fazer comparações entre as médias de duas amostras. Por exemplo, caso o interesse seja testar a hipótese nula \(H_0\): \(\bar{x_1}\) = \(\bar{x_2}\) versus uma hipótese alternativa \(\bar{x_1}\) > \(\bar{x_2}\) ou, de outro modo \(\bar{x_1}\) \(\neq\) \(\bar{x_2}\). Nesse caso, a estatística do teste é baseada na média amostral.

Se X tem distribuição normal com média e variância conhecida, pode ser demonstrado que a média amostral tem distribuição normal com média e variância \(s^2\)/n, em que n é o tamanho da amostra. A estatística do teste será: \(t_{calculado}\) = Média amostral - média/ (desv.pad./raiz de n).

Regra de decisão:

  • Se \(t_{calculado}\) \(\geq\) \(t_{tabelado}\): rejeita-se a hipótese \(H_0\).
  • Se \(t_{calculado}\) < \(t_{tabelado}\): não rejeita-se a hipótese \(H_0\).

O valor tabelado de \(t\) é obtido em tabelas apropriadas, ou no próprio R, usando a função \(\color{magenta}{pt()}\), de acordo com o nível de significância (\(\alpha\)). No caso, de teste \(t\) bilateral tem-se \(t_{tabelado}\) = t(\(\alpha\)/2; n-1). A seguir, considere os diâmetros de árvores de duas amostras diferentes:

dap1 <- c(30.5,35.3,33.2,40.8,42.3,41.5,36.3,43.2,34.6,38.5)

dap2 <- c(28.2,35.1,33.2,35.6,40.2,37.4,34.2,42.1,30.5,38.4)

11.1.1 Teste \(t\) para uma média

Aqui, testar-se-á “dap1” tem média \(\geq\) 35, estatisticamente. Então, as hipóteses do teste são:

  • \(H_0\): \(\bar{dap}\) = 35

  • \(H_1\): \(\bar{dap}\) \(\geq\) 35

O ambiente R dispõe da função \(\color{magenta}{t.test()}\) para aplicação do teste \(t\)-Student. A interpretação do resultado (valor de t e valor de p): \(t_{calculado}\) \(>\) \(t_{tabelado}\); \(p\)-valor < 0.05.

t.test(dap1,                                # amostra a ser testada
       mu=35,                               # hipótese de nulidade
       alternativa = "greater")             # teste unilateral à direita
## 
##  One Sample t-test
## 
## data:  dap1
## t = 1.9323, df = 9, p-value = 0.08535
## alternative hypothesis: true mean is not equal to 35
## 95 percent confidence interval:
##  34.5528 40.6872
## sample estimates:
## mean of x 
##     37.62

11.1.2 Teste \(t\) para as médias de duas amostras independentes

Agora, presumir-se-á que as amostras são oriundas de duas populações diferentes e que ambas possuem variâncias homogêneas e distribuição normal. Suponha que o interesse seja testar se as amostras (dap1 e dap2) possuem médias estatisticamente iguais (\(\alpha\) = 1%), e que as amostras sejam independentes e oriundas de distribuição normal.

Então, as hipóteses do teste são:

  • \(H_0\): \(\bar{dap_1}\) = \(\bar{dap_2}\)

  • \(H_1\): \(\bar{dap_1}\) \(\neq\) \(\bar{dap_2}\)

A função \(\color{magenta}{t.test()}\) pode ser usada novamente:

t.test(dap1, dap2,                           # amostras a serem comparadas
       conf.level = 0.99)                    # nível de significância
## 
##  Welch Two Sample t-test
## 
## data:  dap1 and dap2
## t = 1.1148, df = 17.999, p-value = 0.2796
## alternative hypothesis: true difference in means is not equal to 0
## 99 percent confidence interval:
##  -3.369829  7.629829
## sample estimates:
## mean of x mean of y 
##     37.62     35.49

Interpretação do resultado: \(p\)-valor > 0.01, não rejeita-se a hipótese \(H_0\). Ou seja, as amostras vêm de populações com mesma média.

IMPORTANTE: Não estamos garantindo que as médias amostrais das duas populações são iguais, mas apenas mencionando, com base nessas amostras, que não existem argumentos que provem o contrário.

11.1.3 Teste \(t\) para médias de duas amostras dependentes

Esta é uma situação na qual os valores das duas amostras são coletados de certo número n de indivíduos (mesmas árvores), caracterizando pares de valores dos mesmos indivíduos, acarretando dependência entre as amostras. Dizemos, então, que os dados são pareados (teste \(t\)-pareado). Assim, para o mesmo conjunto de dados (dap1 e dap2), com nível de significância de 1%, considerar as seguintes hipóteses:

  • \(H_0\): \(\bar{dap_1}\) = \(\bar{dap_2}\)

  • \(H_1\): \(\bar{dap_1}\) \(\neq\) \(\bar{dap_2}\)

Novamente pode-se usar a função \(\color{magenta}{t.test()}\), porém utilizar o argumento paired=TRUE, informando que as amostras são dependentes (ou pareadas).

t.test(dap1, dap2,
       conf.level = 0.99,          # nível de significância
       paired = TRUE)              # afirma dependência entre as amostras
## 
##  Paired t-test
## 
## data:  dap1 and dap2
## t = 3.6493, df = 9, p-value = 0.005323
## alternative hypothesis: true difference in means is not equal to 0
## 99 percent confidence interval:
##  0.2331487 4.0268513
## sample estimates:
## mean of the differences 
##                    2.13

12 Aplicações Florestais

12.1 Análise de Variância (ANOVA)

Análise de Variância (ANOVA) é uma técnica estatística que permite decompor a variação total existente no experimento em variação devido à diferença entre efeitos dos tratamentos e na variação devido ao acaso (erro experimental ou resíduo). De outro modo, Procedimento estatístico para testar a hipótese de que a média de três ou mais populações são iguais, baseado na análise das variâncias amostrais. Apesar do nome, é um teste de comparação de médias ! Entretanto, assim se chama pois permite decompor a variação total do experimento em função da variação dos efeitos dos tratamentos e da variação devido ao acaso (resíduos).

VARIAÇÃO TOTAL = EFEITO DOS TRATAMENTOS (fatores controlados) + EFEITO DO ERRO EXPERIMENTAL OU RESÍDUO (Fatores não-controlados)

Os dados amostrais são separados em grupos, segundo uma características específicas (fatores). Variam de acordo com os diferentes tipos de de delineamentos experimentais que podem ser:

a) DIC (Delineamento Inteiramente Casualizado);

b) DBC (Delineamento em Blocos Casualizados); e

c) DQL (Delineamento em Quadrado Latino).

O Teste F (Fisher-Snedecor) é usado para testar a ANOVA de um DIC. As Hipóteses \(H_0\) e \(H_1\) são:

\(H_0\): Todas as médias dos tratamentos são iguais entre si (\(\bar{x_1}\)=\(\bar{x_2}\)=\(\bar{x_3}\)=…= \(\bar{x_n}\)).

\(H_1\): Há pelo menos dois tratamentos cujas médias são diferentes entre si.

Regra de decisão:

Rejeita \(H_0\): Se \(F_{calculado}\) \(>\) \(F_{tabelado}\) (há pelo menos dois tratamentos com médias diferentes).

Não rejeita \(H_0\): Se \(F_{calculado}\) \(\leq\) \(F_{tabelado}\) (todas as médias estatisticamente iguais entre si).

12.1.1 Delineamento Inteiramente Casualizado (DIC)

O DIC é o mais simples dos delineamentos experimentais. Utiliza-se do princípio básico da repetição e casualização. No DIC os tratamentos experimentais são distribuídos às unidades experimentais de forma completamente aleatória (por sorteio). Possui flexibilidade quanto ao número de repetições por tratamento. É recomendado quando pode ser dada condições homogêneas ou uniformes para todas as unidades experimentais.

Para fins de aplicação prática no R, considere a necessidade de estudos relativos ao comportamento da espécie \(\color{red}{\textit{Schizolobium parahyba}}\) \(\color{red}{var. amazonicum}\) em situações de viveiro. Assim, procedeu-se a instalação de um experimento sob o DIC com intuito de avaliar o crescimento em altura da espécie sob diferentes condições de sombreamento. Para tanto, foram estabelecidos quatro tratamento (pleno sol, 20%, 50% e 70% de sombreamento) com cinco repetições de 25 sementes. Os dados estão no arquivo parica.txt e correspondem aos valores médios da altura, em centímetros, obtidos após trinta dias de germinadas as sementes.

parica <- read.table(file = "parica.txt", sep="", header=T)

print(parica)
##    Trat  Rep
## 1    T1 20.0
## 2    T1 22.5
## 3    T1 25.0
## 4    T1 23.5
## 5    T1 17.5
## 6    T2 23.5
## 7    T2 27.5
## 8    T2 25.0
## 9    T2 26.0
## 10   T2 23.5
## 11   T3 17.5
## 12   T3 19.0
## 13   T3 19.5
## 14   T3 20.0
## 15   T3 21.5
## 16   T4 30.0
## 17   T4 33.5
## 18   T4 27.5
## 19   T4 26.0
## 20   T4 26.5

Inicialmente, vamos fazer uma anáilise exploratória dos dados. Dentre outras coisas, é importante conhecer a média e a variância para cada tratamento:

summary(parica)                       # um resumo
##  Trat        Rep       
##  T1:5   Min.   :17.50  
##  T2:5   1st Qu.:20.00  
##  T3:5   Median :23.50  
##  T4:5   Mean   :23.75  
##         3rd Qu.:26.12  
##         Max.   :33.50

# média de altura em cada tratamento?
media <- tapply(parica$Rep, parica$Trat, mean) 
print(media)
##   T1   T2   T3   T4 
## 21.7 25.1 19.5 28.7

# variância da altura em cada tratamento?
var <- tapply(parica$Rep, parica$Trat, var)
print(var)
##    T1    T2    T3    T4 
## 8.825 2.925 2.125 9.575

bartlett.test(parica$Rep, parica$Trat)  # homogeneidade de variâncias
## 
##  Bartlett test of homogeneity of variances
## 
## data:  parica$Rep and parica$Trat
## Bartlett's K-squared = 2.9361, df = 3, p-value = 0.4016

Pode-se fazer uma plotagem da relação Tratamento versus Altura da plântula:

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(1,2))

# plot: Rep x Trat
plot(parica$Trat, parica$Rep, type="o", main="Schizolobium parahyba",
      xlab="Tratamentos", ylab="Altura (cm)")
points(media, pch=20, col=2, cex=1.5)      # Adiciona médias/tratamento

# Usando boxplot
boxplot(parica$Rep ~ parica$Trat, main="Schizolobium parahyba",
      xlab="Tratamentos", ylab="Altura (cm)")
points(media, pch=20, col=2, cex=1.5)

Para implementar a ANOVA para um experimento sob o Delineamento Inteiramente Casualizado (DIC) pode-se usar a função \(\color{magenta}{aov()}\) do pacote stats do R-base (R CORE TEAM, 2017). Em seguida, use a função \(\color{magenta}{anova()}\) ou \(\color{magenta}{summary()}\) para obter o quadro de ANOVA.

anova.DIC <- aov(Rep~Trat,data=parica)

anova(anova.DIC)
## Analysis of Variance Table
## 
## Response: Rep
##           Df Sum Sq Mean Sq F value    Pr(>F)    
## Trat       3 242.95  80.983  13.814 0.0001049 ***
## Residuals 16  93.80   5.863                      
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Uma análise gráfica dos resultados da ANOVA para o DIC:

par(mfrow=c(2,2))
plot(anova.DIC)                   # gráficos para análise dos resíduos

Interpretação: Há diferença entre pelo menos 2 tratamentos (rejeita-se \(H_0\)).

Quando há rejeição de \(H_0\) (\(F_{calculado}\) \(>\) \(F_{tabelado}\)), constata-se que as médias dos tratamentos não são todas iguais entre si. Entretanto, o teste F não permite identificar quais tratamentos diferem entre si. Ou seja, quem é diferente de quem? Para identificar essas diferenças é necessário realizar testes post-hoc ou Testes de comparações múltiplas. Diversos testes de comparaçoes existem, por exemplo, Teste de Tukey, Teste de Duncan, etc. Assim, para o exemplo do Paricá aplicar-se-á o teste de comparações múltiplas de Tukey.

Tukey <- TukeyHSD(anova.DIC)
plot(Tukey)

12.1.2 Pressupostos para realização de testes lineares (ANOVA, Regressão Linear)

Para atender as premissas de modelos lineares é preciso, previamente às análises, verificar a normalidade dos resíduos e a homocedasticidade das variâncias.

Normalidade dos erros experimentais: Os erros experimentais devem ser normalmente distribuídos Homocedasticidade das variâncias: os erros experimentais devem possuir homogeneidade de variâncias. Importante para validar os testes de comparação de médias.

Teste de normalidade mais comum: Shapiro-Wilk

A normalidade é admitida quando um valor de \(p\) > 0,05 (\(H_0\) = existem evidências para admitir a normalidade dos resíduos).

shapiro.test(resid(anova.DIC))
## 
##  Shapiro-Wilk normality test
## 
## data:  resid(anova.DIC)
## W = 0.98613, p-value = 0.9876

O gráfico Normal Q-Q plot pode ser obtido usando as funções \(\color{magenta}{qqnorm()}\) e \(\color{magenta}{qqline()}\).

qqnorm (resid(anova.DIC))       # obtendo o papel de probabilidade normal.
qqline(resid(anova.DIC))        # inserindo uma linha auxiliar (linear).

Homogeneidade de variâncias - Teste de Levene Para testar a Homogeneidade de variâncias pode ser usar o pacote car (FOX; WEISBERG, 2011). Execute install.packages(“car”), caso não tenha instalado. A homogeneidade é admitida quando \(p\) > 0,05).

library(car)
leveneTest(Rep~Trat,parica)
## Levene's Test for Homogeneity of Variance (center = median)
##       Df F value Pr(>F)
## group  3  0.7217 0.5536
##       16

12.2 Regressão Linear

Regressão linear simples: utilizada para analisar relações entre variáveis contínuas. No R, para especificar um modelo é preciso usar a notação de fórmulas. Por exemplo, para um modelo de regressão com uma variável resposta Y (ou dependente) e uma variável preditora X (ou independente) a notação de fórmula a ser usada no R é: Y ~ X. Em que, o argumento ~ (til) significa em relação a… ou modelado por…. Ou seja, Y em relação a X, ou Y modelado por X. Caso hajam duas variáveis preditoras em seu modelo a formula seria Y~X1+X2. Para implementar uma regressão linear no ambiente R pode-se usar a função \(\color{magenta}{lm()}\) disponível no R-base. A função retorna os valores dos coeficientes betas estimados através do Método de Mínimos Quadrados. Para fins de exemplificação serão usados os dados biométricos das 30 árvores de \(\color{red}{\textit{Tectona grandis}}\). As variáveis disponíveis são: DAP (cm), H (m) e Volume (m³).

teca <- fread("Tectona.csv")
teca
##     Arvore  DAP     H     Volume
##  1:      1  6.6  8.90 0.01659735
##  2:      2  6.8  7.95 0.01667180
##  3:      3  7.0  6.87 0.01418640
##  4:      4  7.1 12.70 0.02669411
##  5:      5  7.5 11.74 0.02845194
##  6:      6  9.9 13.84 0.06552577
##  7:      7 10.8 15.25 0.04901434
##  8:      8 11.2 13.00 0.05769142
##  9:      9 11.3 14.60 0.06561012
## 10:     10 11.7 15.60 0.08286705
## 11:     11 12.6 17.20 0.10011879
## 12:     12 14.0 16.60 0.12726937
## 13:     13 14.3 17.87 0.15799148
## 14:     14 14.6 17.90 0.14122551
## 15:     15 14.9 16.50 0.13180905
## 16:     16 15.0 18.30 0.15302855
## 17:     17 15.3 17.40 0.16190700
## 18:     18 15.4 17.55 0.13909680
## 19:     19 16.2 16.99 0.19180080
## 20:     20 17.1 17.72 0.15774958
## 21:     21 17.4 16.20 0.19560797
## 22:     22 18.0 16.10 0.19684120
## 23:     23 18.1 15.34 0.25018280
## 24:     24 19.2 16.15 0.20325802
## 25:     25 19.8 14.38 0.26157554
## 26:     26 20.6 22.00 0.31693957
## 27:     27 22.5 20.60 0.37742654
## 28:     28 23.5 16.70 0.26324442
## 29:     29 23.8 22.80 0.39531037
## 30:     30 32.6 21.55 0.60309453
##     Arvore  DAP     H     Volume

12.2.1 Gráficos de dispersão

attach(teca)
par(mar = c(4.5,3.5,1.5,1), mgp = c(2,1,0), mfrow = c(1,2))

plot(DAP,Volume, type = "p", main=NULL, font.main=NULL, col.main=NULL, 
     xlab="DAP (cm)", ylab=expression(Volume~(m^3)), font.lab=1, col.lab="black",
     font.axis=1, col.axis = "black")

plot(H,Volume, type = "p", main=NULL, font.main=NULL, col.main=NULL, 
     xlab="Altura (m)", ylab=expression(Volume~(m^3)), font.lab=1, col.lab="black",
     font.axis=1, col.axis = "black")

detach(teca)

12.2.2 Ajuste de modelos

Ajustar os modelos volumétricos de Berkhout \(V = \beta_0 + \beta_1~(DAP)\), Kopezky-Gehrardt (\(V = \beta_0 + \beta_1~(DAP^2)\)) e Shumacher-Hall (\(lnV = \beta_0 + \beta_1~(lnDAP) + \beta_2~(lnH)\):

Berkhout <- lm(Volume ~ DAP, data=teca)                 # Berkhout
KGehrardt <- lm(Volume ~ I(DAP^2), data=teca)           # Kopezky-Gehrardt
SHall <- lm(log(Volume) ~ log(DAP) + log(H), data=teca) # Shumacher-Hall
print(Berkhout); print(KGehrardt); print(SHall)
## 
## Call:
## lm(formula = Volume ~ DAP, data = teca)
## 
## Coefficients:
## (Intercept)          DAP  
##    -0.16122      0.02152
## 
## Call:
## lm(formula = Volume ~ I(DAP^2), data = teca)
## 
## Coefficients:
## (Intercept)     I(DAP^2)  
##   0.0039133    0.0006098
## 
## Call:
## lm(formula = log(Volume) ~ log(DAP) + log(H), data = teca)
## 
## Coefficients:
## (Intercept)     log(DAP)       log(H)  
##     -9.4574       1.8982       0.8301

Para obter informações mais detalhadas do ajuste pode-se usar a função \(\color{magenta}{summary()}\). Com uso da função \(\color{magenta}{summary()}\) pode-se obter informações do erros-padrão (Std. Error) das estimativas dos coeficientes de regressão, Erro-Padrão de estimativa (Residual standard error), Coeficiente de Determinação (Multiple R-Squared) e Coeficiente de Determinação Ajustado (Adjusted R-squared). Além disso, pode-se vizualizar o teste F da significâcnia da regressão e o(s) teste(s) \(t\)-student para significância do(s) coeficiente(s) da regressão.

summary(Berkhout)
## 
## Call:
## lm(formula = Volume ~ DAP, data = teca)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.081155 -0.020937 -0.006857  0.027424  0.062904 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -0.161216   0.017116  -9.419 3.55e-10 ***
## DAP          0.021516   0.001053  20.428  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.03377 on 28 degrees of freedom
## Multiple R-squared:  0.9371, Adjusted R-squared:  0.9349 
## F-statistic: 417.3 on 1 and 28 DF,  p-value: < 2.2e-16
summary(KGehrardt)
## 
## Call:
## lm(formula = Volume ~ I(DAP^2), data = teca)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.077437 -0.015987 -0.004587  0.014409  0.064796 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 3.913e-03  9.023e-03   0.434    0.668    
## I(DAP^2)    6.098e-04  2.685e-05  22.710   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.03056 on 28 degrees of freedom
## Multiple R-squared:  0.9485, Adjusted R-squared:  0.9467 
## F-statistic: 515.8 on 1 and 28 DF,  p-value: < 2.2e-16
summary(SHall)
## 
## Call:
## lm(formula = log(Volume) ~ log(DAP) + log(H), data = teca)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.33671 -0.08354  0.00374  0.05991  0.30833 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -9.4574     0.2793 -33.862  < 2e-16 ***
## log(DAP)      1.8982     0.1183  16.052 2.47e-15 ***
## log(H)        0.8301     0.1760   4.717 6.51e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1428 on 27 degrees of freedom
## Multiple R-squared:  0.9805, Adjusted R-squared:  0.9791 
## F-statistic: 679.1 on 2 and 27 DF,  p-value: < 2.2e-16

A função \(\color{magenta}{anova()}\) permite obter a tabela de ANOVA da Regressão:

anova(Berkhout)
## Analysis of Variance Table
## 
## Response: Volume
##           Df  Sum Sq Mean Sq F value    Pr(>F)    
## DAP        1 0.47588 0.47588  417.32 < 2.2e-16 ***
## Residuals 28 0.03193 0.00114                      
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(KGehrardt)
## Analysis of Variance Table
## 
## Response: Volume
##           Df  Sum Sq Mean Sq F value    Pr(>F)    
## I(DAP^2)   1 0.48166 0.48166  515.77 < 2.2e-16 ***
## Residuals 28 0.02615 0.00093                      
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(SHall)
## Analysis of Variance Table
## 
## Response: log(Volume)
##           Df  Sum Sq Mean Sq  F value    Pr(>F)    
## log(DAP)   1 27.2316 27.2316 1335.981 < 2.2e-16 ***
## log(H)     1  0.4536  0.4536   22.255 6.508e-05 ***
## Residuals 27  0.5503  0.0204                       
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Pode-se visualizar a reta ajustada para o modelo de Berkhout (\(V = \beta_0 + \beta_1~(DAP)\)):

par(mar = c(4.5,3.5,1.5,1), mgp = c(2,1,0))

plot(teca$Volume~teca$DAP, main="Berkhout", 
     xlab="DAP (cm)", ylab = expression(Volume~(m^3)))
abline(Berkhout,lty=2, col="red")

#abline(coef(Berkhout))

Outras informaçoes importantes podem ser obtidas. Por exemplo, os valores preditos pelo modelo de regressão pode ser extraído com uso da função e os reśiduos com a função \(\color{magenta}{residuals()}\).

predict(Berkhout)
##             1             2             3             4             5 
## -0.0192131451 -0.0149100434 -0.0106069417 -0.0084553909  0.0001508125 
##             6             7             8             9            10 
##  0.0517880326  0.0711519902  0.0797581936  0.0819097444  0.0905159478 
##            11            12            13            14            15 
##  0.1098799053  0.1400016171  0.1464562696  0.1529109221  0.1593655746 
##            16            17            18            19            20 
##  0.1615171255  0.1679717780  0.1701233289  0.1873357356  0.2066996931 
##            21            22            23            24            25 
##  0.2131543457  0.2260636507  0.2282152015  0.2518822608  0.2647915658 
##            26            27            28            29            30 
##  0.2820039725  0.3228834385  0.3443989469  0.3508535994  0.5401900734
residuals(Berkhout)
##            1            2            3            4            5 
##  0.035810493  0.031581847  0.024793338  0.035149504  0.028301132 
##            6            7            8            9           10 
##  0.013737736 -0.022137647 -0.022066772 -0.016299623 -0.007648902 
##           11           12           13           14           15 
## -0.009761117 -0.012732243  0.011535210 -0.011685415 -0.027556521 
##           16           17           18           19           20 
## -0.008488576 -0.006064774 -0.031026526  0.004465061 -0.048950116 
##           21           22           23           24           25 
## -0.017546378 -0.029222451  0.021967602 -0.048624240 -0.003216027 
##           26           27           28           29           30 
##  0.034935602  0.054543104 -0.081154531  0.044456775  0.062904453

12.2.3 Análise de Resíduos

Os resíduos da regressão linear devem ser julgados quanto às pressuposições de normalidade, autocorrelação e homocedasticidade. O teste para normalidade dos resíduos pode ser realizado usado a função \(\color{magenta}{shapiro.test}\). A autocorrelação pode ser detectada com uso da função \(\color{magenta}{durbinWatsonTest}\) e a heterocedasticidade dos resíduos através da função \(\color{magenta}{Breusch-Pagan}\).

12.2.3.1 Normalidade dos resíduos

Realizando o teste de normalidade dos resíduos (\(\alpha\) = 0,05) para os modelos de Berkhout, Kopezky-Gehrardt e Shumacher-Hall:

Teste para normalidade (valores de \(p\) > 0,05 indicam resíduos com distribuição normal).

shapiro.test(Berkhout$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  Berkhout$residuals
## W = 0.97824, p-value = 0.7772
shapiro.test(KGehrardt$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  KGehrardt$residuals
## W = 0.96446, p-value = 0.4005
shapiro.test(SHall$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  SHall$residuals
## W = 0.98224, p-value = 0.8815

12.2.3.2 Autocorrelação de resíduos

O teste Durbin-Watson (\(\alpha\) = 0,05) pode ser utilizado para apontar indícios de autocorrelação dos resíduos em modelos de regressão linear. Quando \(p\)-value \(\geq\) 0,05 não existem evidências de que os resíduos sejam autocorrelacionados. Para tanto, pode-se usar a função \(\color{magenta}{durbinWatsonTest}\) disponível no pacote car (FOX; WEISBERG, 2011).

library(car)
durbinWatsonTest(Berkhout)
##  lag Autocorrelation D-W Statistic p-value
##    1       0.0490722       1.73776    0.36
##  Alternative hypothesis: rho != 0
durbinWatsonTest(KGehrardt)
##  lag Autocorrelation D-W Statistic p-value
##    1      -0.2825325      2.466242   0.288
##  Alternative hypothesis: rho != 0
durbinWatsonTest(SHall)
##  lag Autocorrelation D-W Statistic p-value
##    1      -0.1096209      2.135885   0.924
##  Alternative hypothesis: rho != 0

12.2.3.3 Heterocedasticidade dos resíduos

O teste Breusch-Pagan (\(\alpha\) = 0,05) pode ser usado para detectar homocedasticidade de variâncias dos resíduos. Quando \(p\)-value \(<\) 0,05 a hipótese nula (\(H_0\)) é rejeitada, isto é, há presença de heteroscedasticidade. Para aplicar o teste pode-se usar a função \(\color{magenta}{bptest}\) disponível no pacote lmtest (ZEILEIS; HOTHORN, 2002).

library(lmtest)
bptest(Berkhout)
## 
##  studentized Breusch-Pagan test
## 
## data:  Berkhout
## BP = 9.8249, df = 1, p-value = 0.001722
bptest(KGehrardt)
## 
##  studentized Breusch-Pagan test
## 
## data:  KGehrardt
## BP = 12.322, df = 1, p-value = 0.0004476
bptest(SHall)
## 
##  studentized Breusch-Pagan test
## 
## data:  SHall
## BP = 2.018, df = 2, p-value = 0.3646

A função \(\color{magenta}{plot}\) por default gera quatro gráficos uteis para detectar normalidade, homocedasticidade e valores influentes:

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))
plot(Berkhout)

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))
plot(KGehrardt)

par(mar = c(4.5,3,1.5,1), mgp = c(2,1,0), mfrow = c(2,2))
plot(SHall)

12.2.4 Multicolinearidade (modelos múltiplos)

A inexistência de multicolinearidade é outra importante pressuposição que deve ser analisada em modelos de regressão linear múltipla. O grau de confundimento entre variáveis preditora pode ser verificado por meio da estatística Variance Inflation Factor – (VIF), para detectar problemas de multicolinearidade. É recorrente o uso de VIF \(>\) 10 como critério para afirmar a existência de multicolinearidade no modelo de regressão linear múltipla. Para obter o valor da estatítica pode-se usar a função \(\color{magenta}{vif}\) do pacote faraway (FARAWAY, 2016).

library(faraway)
vif(SHall)
## log(DAP)   log(H) 
## 3.339837 3.339837

12.3 Amostragem Aleatória Simples (AAS)

É o procedimento fundamental de seleção a partir do qual derivam os demais processos de amostragem (PÉLLICO NETO; BRENA, 1997; SANQUETTA et al., 2009). A Amostragem Aleatória Simples (AAS) baseia-se num processo estritamente aleatório, onde as unidades amostrais (UAs) são selecionadas com igual probabilidade (1/N), em que N é o nº total de unidades de amostras que compõem o espaço amostral, ou seja, a população amostrada (QUEIROZ, 1998). A seleção das unidades amostrais pode ser realizada com ou sem reposição. No sorteio com reposição uma determinada unidade de amostra pode ser sorteada mais de uma vez para compor a amostra. No sorteio sem reposição uma unidade de amostra poderá ser sorteada somente uma única vez para compor a amostra (PÉLLICO NETO; BRENA, 1997). Em inventários florestais a AAS é geralmente conduzida através de um sorteio sem reposição. Além disso, expõe que a inclusão de uma unidade amostral mais de uma vez na amostra refletirá uma homogeneização da variância entre as UAs (QUEIROZ, 1998).

12.3.1 Estimadores da AAS

As principais estimativas a serem obtidas para a AAS são:

  1. Média aritmética (\(\bar{x}\));
  2. Variância (\(S_x^2\));
  3. Desvio Padrão (\(S_x\));
  4. Coeficiente de variação (\(CV\%\));
  5. Intensidade amostral (\(n\));
  6. Variância da média (\(S_{\bar{x}}^2\));
  7. Erro padrão da média (\(S_{\bar{x}}\));
  8. Erro de amostragem: absoluto (\(E_a\)) e relativo (\(E_r\));
  9. Intervalo de confiança para média (\(IC_{\bar{x}}\));
  10. Total da população (\(\hat{X}\)); e
  11. Intervalo de confiança para o total (\(IC_{\hat{X}}\)).

12.3.2 Estimando os parâmetros da AAS

A seguir as principais estimativas da AAS serão obtidas usando a linguagem R. Os dados utilizados foram extraídos do livro Inventário Florestal: Planejamento e execução, com o seguinte enunciado: “Em um talhão de \(\color{red}{\textit{Pinus taeda}}\) plantado em uma área de 40 hectares foi realizado um inventário, cujo objetivo é estimar o volume de madeira da população em questão. Para a realização do inventário foi utilizado o processo de amostragem aleatória simples,onde se deseja saber quantas parcelas de 600m² devem ser usadas para atingir a precisão desejada. A definição do número ideal de parcelas depende da variabilidade da população. Para isto foi realizado um inventário piloto, onde foram medidas 16 parcelas, com a finalidade de obter a variância da população e, assim, estimar a intensidade amostral para o inventário definitivo. Para os cálculos das estimativas foi considerado que o erro máximo admissível é de 10% e o nível de probabilidade é de 95% (SANQUETTA et al., 2014, p. 110).”

# Carregando o conjunto de dados
AAS <- fread("AAS.csv")
AAS
##     Parcela Volume
##  1:       1  20.85
##  2:       2  19.47
##  3:       3  24.13
##  4:       4  24.34
##  5:       5  25.13
##  6:       6  22.37
##  7:       7  22.51
##  8:       8  19.78
##  9:       9  25.05
## 10:      10  28.84
## 11:      11  23.70
## 12:      12  24.78
## 13:      13  22.58
## 14:      14  23.70
## 15:      15  36.16
## 16:      16  17.83

Obtendo as estatísticas básicas para as unidades amostrais:

1. Média aritmética \(\boldsymbol{(\bar{x})}\) - \(m^3/parcela\):

mean(AAS$Volume)
## [1] 23.82625

2. Variância \(\boldsymbol{(S_x^2)}\) - \((m^3/parcela)^2\)

var(AAS$Volume)
## [1] 17.8215

3. Desvio Padrão \(\boldsymbol{(S_x)}\) - \(m^3/parcela\):

sd(AAS$Volume)
## [1] 4.221552

4. Coeficiente de variação \(\boldsymbol{(CV\%)}\):

coefficient.variation(sd=sd(AAS$Volume),avg=mean(AAS$Volume))*100
## [1] 17.71807

5. Intensidade amostral \(\boldsymbol{(n)}\): A intensidade de amostragem é função: i) da variabilidade da variável de interesse (volume da floresta); ii) do erro de amostragem máximo admissível; e iii) do nível de confiança fixado (PÉLLICO NETO; BRENA, 1997). Assim, para obter a estimativa de \(n\) é necessário obter as seguintes informações:

a) O valor de \(\boldsymbol{E}\) (expectância do erro) - \(m^3/parcela\): Em inventário florestal é usual estabelecer um erro máximo admissível de 10% para estimativa da média. Então, para obter o valor de \(E\) basta fazer:

\[ E = (LE\,.\,\bar{x}) \] Uma função para obter o valor de \(\boldsymbol{E}\):

E <- function(x){
  media = mean(x)
  E = signif(0.1*media, 4)
  return(E)
}

E(AAS$Volume)
## [1] 2.383

b) O número de unidades amostrais possíveis na população \(\boldsymbol{(N)}\): Quantas unidades de amostra de tamanho de 600 m² é possível estabelecer na população, cuja área total é de 400.000m² (40 hectares)? Para obter essa informação basta dividir a área da população pelo tamanho da parcela. Assim, obtêm-se que são possíveis 667 parcelas de 600m² na população.

\[ N = \frac{A}{a} \]

Uma função para obter o valor de \(\boldsymbol{N}\):

N <- function(A,a){
  N <- ceiling(A/a)
  return(N)
}

N = N(400000,600)
N
## [1] 667

c) Determinar se a população é finita ou infinita: Para determinar o número de unidades de amostras necessárias para atender determinada precisão e nível de probabilidade é necessário saber, antecipadamente, se a população é Finita ou Infinita. Para tanto, inicialmente é preciso obter a fração de amostragem \(f\) e, em seguida, abservar a convenção (PÉLLICO NETO; BRENA, 1997):

\[ \begin{cases} Se \quad 1- f \geq 0,98 & \quad \text{População Infinita}\\ Se \quad 1- f < 0,98 & \quad \text{População Finita} \end{cases} \]

A fração de amostragem \(\boldsymbol{(f)}\) é dada pela razão entre o número de unidades de amostra \(\boldsymbol{(n)}\) e o número total de unidades de amostra possíveis na população \(\boldsymbol{(N)}\) (PÉLLICO NETO; BRENA, 1997; SANQUETTA et al., 2014):

\[ f = \frac{n}{N} \]

Uma função para obter o Fator de Correção \(\boldsymbol{FC}\) e constatar a natureza da população. O cálculo intermediário da fração de amostragem \(\boldsymbol{(f)}\) é realizado e também retornado. A função \(FC\) recebe três parâmetros: \(\boldsymbol{x}\) = vetor da variável de interesse; \(\boldsymbol{A}\) = aréa da população; e \(\boldsymbol{a}\) = tamanho da unidade de amostra. O valor de \(\boldsymbol{A}\) e \(\boldsymbol{a}\) devem estar na mesma unidade de medida.

FC <- function(x,A,a){
  n <- length(x)
  N <- ceiling(A/a)
  f <- n/N
  FC <- 1-f
  
  if(FC >= 0.98){
    cat("A população é Infinita. Portanto, despreze o FC na fórmula da n.\n")
  }else{
    cat("A população é Finita. Portanto, use o FC para corrigir n.\n")
  }
  return(list(f=f,FC=FC))
}
FC <- FC(x=AAS$Volume, A=400000, a = 600)
## A população é Finita. Portanto, use o FC para corrigir n.

Determinados os valores de \(E\), \(N\) e constatada a natureza finita da população, pode-se obter a intensidade de amostragem ideal em função da variância:

n <- function(x,A,a){
  N <- ceiling(A/a)
  E = 0.1*mean(x)
  t = qt(1-.05/2, df=length(x)-1)
  n <- ceiling((N*t^2*var(x))/(N*E^2 + t^2*var(x)))
  cat(paste("Para atender ao erro estabelecido você deve amostrar", n, 
            "parcelas.\n"))
  
  if(n <= length(x)){
    cat("Esforço amostral satisfatório. O IF é definitivo!")
  }else{
    cat(paste("Retorne a campo e meça mais", abs(length(x)-n), "parcelas."))
  }
}
n(x = AAS$Volume, A = 400000, a = 600)
## Para atender ao erro estabelecido você deve amostrar 14 parcelas.
## Esforço amostral satisfatório. O IF é definitivo!

6. Variância da média \(\boldsymbol{(S_{\bar{x}}^2)}\) - \((m^3/parcela)^2\): A variância da média para populações finitas é dada por:

\[ S_{\bar{x}}^2 = \frac{S_x^2}{n}\,.\,\left(\frac{N-n}{N}\right) \]

var(AAS$Volume)/length(AAS$Volume)*(FC$FC)
## [1] 1.087125

7. Erro padrão da média \(\boldsymbol{(S_{\bar{x}})}\) - \((m^3/parcela)\): O erro padrão da média para populações finitas é dado por:

\[ S_{\bar{x}} = \pm\, \frac{S_x}{\sqrt{n}}\,.\,\sqrt{\left(1-f\right)} \]

sbarx <- sd(AAS$Volume)/sqrt(length(AAS$Volume))*(sqrt(FC$FC))
sbarx
## [1] 1.042653

8. Erro de amostragem:

a) Erro de amostragem absoluto \(\boldsymbol{(E_a)}\) - \((m^3/parcela)\): O erro de amostragem absoluto é dado por:

\[ E_a = \pm\, t\,.\,S_{\bar{x}} \]

Ea <- qt(1-.05/2, df=length(AAS$Volume)-1)*sbarx
Ea
## [1] 2.222362

b) Erro de amostragem relativo \(\boldsymbol{(E_r)}\) - \(\%\): O erro de amostragem relativo é dado por:

\[ E_r = \pm\, \frac{t\,.\,S_{\bar{x}}}{\bar{x}}\,.\,100 \]

Er <- Ea/mean(AAS$Volume)*100
Er
## [1] 9.327369

9. Intervalo de confiança para média \(\boldsymbol{(IC_{\bar{x}})}\): O IC para média é dado por:

\[ IC_{\bar{x}} = [\bar{x} - \left(t\,.\,S_{\bar{x}}\right) \leq \bar{X} \leq \bar{x} + \left(t\,.\,S_{\bar{x}}\right) ] = P \]

# Limite inferior para média (LI)
LIbarx <- mean(AAS$Volume)-Ea
LIbarx
## [1] 21.60389

# Limite superior para média (LS)
LSbarx <- mean(AAS$Volume)+Ea
LSbarx
## [1] 26.04861

Portanto, o IC para média é: \(IC_{\bar{x}} = [21,61\, m^3/parcela \leq \bar{X} \leq 26,05\, m^3/parcela ] = 95\%\).

10. Total da população \(\boldsymbol{(\hat{X})}\) - \(m^3\): O volume estimado para o total da população é dado por:

\[ \hat{X} = N\,.\,\bar{x} \]

hatX <- N*mean(AAS$Volume)
hatX
## [1] 15892.11

11. Intervalo de confiança para o total \(\boldsymbol{(IC_{\hat{X}})}\): O IC para a estimativa do volume total da população é dado por:

\[ IC_{\hat{X}} = [\hat{X} - N\left(t\,.\,S_{\bar{x}}\right) \leq X \leq \hat{X} + N\left(t\,.\,S_{\bar{x}}\right) ] = P \]

# Limite inferior para total da população (LI)
LIhatx <- hatX - N*Ea
LIhatx
## [1] 14409.79

# Limite superior para total da população (LS)
LShatx <- hatX + N*Ea
LShatx
## [1] 17374.42

Portanto, o IC para o total da população é: \(IC_{\hat{X}} = [14.409,8\, m^3 \leq \bar{X} \leq 17.374,4\, m^3] = 95\%\).

Observe que para melhor compreensão dos cálculos os parâmetros da AAS foram obtidos passo a passo. Porém, é possível obter todas as estimativas criando apenas uma única função no ambiente R. A seguir é apresentada uma função genérica para obter as estimativas da AAS. A função \(AIA\) recebe três parâmetros: \(\boldsymbol{x}\) = vetor da variável de interesse; \(\boldsymbol{A}\) = aréa da população; e \(\boldsymbol{a}\) = tamanho da unidade de amostra. Internamente a função faz o cálculo do Fator de Proporcionalidade (FP) para obter os parâmetros estimados em hectare (ha):

AIA <- function(x,A,a){
  FP <- 10000/a
  x <- x*FP
  Soma <- sum(x)
  Media <- mean(x, na.rm = TRUE)
  Variancia <- var(x)
  N <- ceiling(A/a)
  f <- length(x)/N
  FC <- 1-f
  E = 0.1*mean(x)
  t = qt(1-.05/2, df=length(x)-1)
  
  if(FC >= 0.98){
    cat("\n-------------------------------------------------------------\n
        A população é Infinita.\n")
    n <- ceiling((t^2*var(x))/E^2)
    cat("Para atender ao erro estabelecido você deve amostrar", n, "parcelas.\n")
    VarM <- var(x)/length(x)
    SdM <- sqrt(VarM)
    Ea <- t*SdM
    Er <- (Ea/Media)*100
    ICI <- Media - Ea
    ICS <- Media + Ea
    TotPop <- N*Media
    ICIP <- ICI*A
    ICSP <- ICS*A
    
    if(n <= length(x)){
    cat("Esforço amostral satisfatório. O IF é definitivo!")
    }else{
    cat("Retorne a campo e meça mais", abs(length(x)-n), "parcelas.")
    }

  }else{
    cat("\n-------------------------------------------------------------\n")
    cat("A população é Finita -", "FC =",round(FC,3),"\n")
    n <- ceiling((N*t^2*var(x))/(N*E^2 + t^2*var(x)))
    cat("Para atender ao erro estabelecido você deve amostrar", n, "parcelas.\n")
    VarM <- var(x)/length(x)*FC
    SdM <- (sd(x)/sqrt(length(x)))*sqrt(FC)
    Ea <- t*SdM
    Er <- (Ea/Media)*100
    ICI <- Media - Ea
    ICS <- Media + Ea
    TotPop <- N*Media
    ICIP <- ICI*A
    ICSP <- ICS*A
    
    if(n <= length(x)){
    cat("Esforço amostral satisfatório. O IF é definitivo!")
    }else{
    cat("ATENÇÃO: Retorne a campo e meça mais", abs(length(x)-n), "parcelas.")
    }
    
  }
    cat("\n-------------------------------------------------------------\n")
  
  df <- format(data.frame(Parametros=
                            c("Soma", "Média", "Número de amostras possíveis", 
                              "Fração de amostragem", "Erro máximo admissível",
                              "t-student", "Intensidade amostral", 
                              "Variância da média", "Erro padrão da Média", 
                              "Erro de amostragem absoluto", 
                              "Erro de amostragem relativo", 
                              "IC inferior para média", 
                              "IC superior para média","Total da população", 
                              "IC inferior para total da população", 
                              "IC superior para total da população"),
                   Estimativas=c(Soma, Media, N, f, E, t, n,
                                        VarM, SdM, Ea, Er, ICI, ICS,
                                        TotPop, ICIP, ICSP)), justify = "right", 
               digits = 6, nsmall=3, scientific=FALSE)
  return(df)
}
AIA(x = AAS$Volume, A = 400000, a = 600)
## 
## -------------------------------------------------------------
## A população é Finita - FC = 0.976 
## Para atender ao erro estabelecido você deve amostrar 14 parcelas.
## Esforço amostral satisfatório. O IF é definitivo!
## -------------------------------------------------------------
##                             Parametros      Estimativas
## 1                                 Soma      6353.666667
## 2                                Média       397.104167
## 3         Número de amostras possíveis       667.000000
## 4                 Fração de amostragem         0.023988
## 5               Erro máximo admissível        39.710417
## 6                            t-student         2.131450
## 7                 Intensidade amostral        14.000000
## 8                   Variância da média       301.979212
## 9                 Erro padrão da Média        17.377549
## 10         Erro de amostragem absoluto        37.039369
## 11         Erro de amostragem relativo         9.327369
## 12              IC inferior para média       360.064798
## 13              IC superior para média       434.143536
## 14                  Total da população    264868.479167
## 15 IC inferior para total da população 144025919.023034
## 16 IC superior para total da população 173657414.310299

12.4 Análise fitossociológica

12.4.1 Estrutura Horizontal

A análise fitossociológica da floresta abrange a estimativa de diversos parâmetros. Os parâmetros fitossociológicos da estrutura horizontal podem ser expressos, em valores absolutos e relativos (MUELLER-DOMBOIS; ELLENBERG, 1974).

12.4.2 Estimadores da estrutura horizontal

Os principais parâmetros fitossociológicos da estrutura horizontal (MUELLER-DOMBOIS; ELLENBERG, 1974; SANQUETTA et al., 2014; SOUZA; SOARES, 2013):

  1. Densidade absoluta (\(DA_{i}\)) da \(i\)-ésima espécie, em número de individuos por hectare, por espécie;
  2. Densidade relativa (\(DR_{i}\)) da \(i\)-ésima espécie, em porcentagem;
  3. Dominância absoluta (\(DoA_{i}\)) da \(i\)-ésima espécie (\(m^2.ha^{-1}\));
  4. Dominância relativa (\(DoR_{i}\)) da \(i\)-ésima espécie, em porcentagem;
  5. Frequência absoluta (\(FA_{i}\)) da \(i\)-ésima espécie, em porcentagem;
  6. Frequência relativa (\(FR_{i}\)) da \(i\)-ésima espécie, em porcentagem;
  7. Valor de cobertura (\(VC_{i}\)) da \(i\)-ésima espécie, em porcentagem;
  8. Porcentagem de cobertura (\(PC_{i}\)) da \(i\)-ésima espécie;
  9. Valor de importância (\(VI_{i}\)) da \(i\)-ésima espécie, em porcentagem; e
  10. Porcentagem de importância (\(PI_{i}\)) da \(i\)-ésima espécie.

12.4.3 Estimando os parâmetros da estrutura horizontal

A seguir os principais parâmetros fitossociológicos da estrutura horizontal serão obtidos usando a linguagem R. Os dados foram obtidos através de parcelas permanentes de monitoramento instaladas em Floresta Ombrofila Mista (FOM), com nível de inclusão de 10cm (DAP \(\geq\) 10 cm). Foram estabelecidas 3 parcelas de 1000 \(m^2\) (0.1 \(ha\)), com área total amostra (A) de 0.3 \(ha\). Para fins didáticos, serão apresentados os códigos para obter os parâmetros da estrutura horizontal da espécie \(\color{red}{\textit{Araucaria angustifolia}}\) e, em seguida, mostrar-se-á um código para obter os parâmetros de todas as espécies de uma só vez usando o pacote data.table para manipulação (DOWLE; SRINIVASAN, 2017):

# Carregando o conjunto de dados
library("data.table")
FOM <- fread("Fito.csv")
FOM
##     Parcela                  Especie   DAP
##  1:       1   Araucaria angustifolia  34.5
##  2:       1            Ocotea porosa  56.2
##  3:       1         Ocotea pulchella  13.4
##  4:       1      Maytenus ilicifolia  10.2
##  5:       1      Ilex paraguariensis  10.9
##  6:       1 Campomanesia xanthocarpa  24.7
##  7:       1      Drymis brasiliensis  23.8
##  8:       1       Allophyllus edulis  13.1
##  9:       1      Matayba eleagnoides  31.0
## 10:       1         Cupania vernalis  10.0
## 11:       1  Capsicodendron dinnisii  21.9
## 12:       1   Araucaria angustifolia  76.6
## 13:       1   Araucaria angustifolia  45.9
## 14:       1      Ilex paraguariensis  23.0
## 15:       1      Matayba eleagnoides  17.9
## 16:       1   Araucaria angustifolia  29.9
## 17:       1 Campomanesia xanthocarpa  17.6
## 18:       1      Ilex paraguariensis  13.9
## 19:       1       Allophyllus edulis  12.1
## 20:       1      Ilex paraguariensis  11.3
## 21:       1        Vernonia discolor  23.8
## 22:       2      Ilex paraguariensis  14.5
## 23:       2    Nectandra grandiflora  13.5
## 24:       2         Eugenia uniflora  13.2
## 25:       2 Campomanesia xanthocarpa  22.0
## 26:       2   Araucaria angustifolia  34.6
## 27:       2      Matayba eleagnoides  32.0
## 28:       2         Mimosa scabrella  28.0
## 29:       2   Araucaria angustifolia 134.0
## 30:       2      Ilex paraguariensis  19.5
## 31:       2       Sapium glandulatum  12.9
## 32:       2 Schinus terebinthifolius  23.5
## 33:       2      Ilex paraguariensis  35.0
## 34:       2   Araucaria angustifolia  19.0
## 35:       2      Ilex paraguariensis  27.0
## 36:       2      Ilex paraguariensis  17.6
## 37:       2   Araucaria angustifolia  50.7
## 38:       2    Nectandra grandiflora  16.9
## 39:       2   Nectandra megapotamica  32.7
## 40:       2   Araucaria angustifolia  44.8
## 41:       2      Ilex paraguariensis  21.0
## 42:       2        Luehea divaricata  34.5
## 43:       2         Cedrela fissilis  38.6
## 44:       2      Matayba eleagnoides  23.8
## 45:       3 Piptocarpha angustifolia  27.9
## 46:       3      Ilex paraguariensis  17.5
## 47:       3      Ilex paraguariensis  26.0
## 48:       3 Campomanesia xanthocarpa  22.0
## 49:       3   Araucaria angustifolia  45.0
## 50:       3      Matayba eleagnoides  28.7
## 51:       3      Matayba eleagnoides  19.7
## 52:       3   Araucaria angustifolia  48.0
## 53:       3   Nectandra megapotamica  15.6
## 54:       3            Ocotea porosa  78.9
## 55:       3      Ilex paraguariensis  23.0
## 56:       3      Ilex paraguariensis  16.0
## 57:       3   Araucaria angustifolia  56.0
## 58:       3      Ilex paraguariensis  23.6
## 59:       3      Ilex paraguariensis  19.9
## 60:       3   Araucaria angustifolia  25.6
## 61:       3      Matayba eleagnoides  27.6
## 62:       3    Nectandra grandiflora  19.8
## 63:       3   Araucaria angustifolia  18.9
## 64:       3      Ilex paraguariensis  10.1
## 65:       3         Mimosa scabrella  27.0
## 66:       3 Schinus terebinthifolius  21.0
## 67:       3       Allophyllus edulis  18.4
## 68:       3              Ilex dumosa  35.7
## 69:       3     Tabebuia avellanedae  29.6
## 70:       3       Sapium glandulatum  23.6
##     Parcela                  Especie   DAP

Inicialmente, pode-se fazer uma breve inspeção dos dados:

nrow(FOM)
## [1] 70
names(FOM)
## [1] "Parcela" "Especie" "DAP"
dim(FOM)
## [1] 70  3
# n = Número total de indivíduos amostrados na j-ésima parcela
FOM[, .(n=.N), by=Parcela][]
##    Parcela  n
## 1:       1 21
## 2:       2 23
## 3:       3 26
# Número de indivíduos amostrados da i-ésima espécie na j-ésima parcela
FOM[, .(ni=.N), by=c("Parcela", "Especie")]
##     Parcela                  Especie ni
##  1:       1   Araucaria angustifolia  4
##  2:       1            Ocotea porosa  1
##  3:       1         Ocotea pulchella  1
##  4:       1      Maytenus ilicifolia  1
##  5:       1      Ilex paraguariensis  4
##  6:       1 Campomanesia xanthocarpa  2
##  7:       1      Drymis brasiliensis  1
##  8:       1       Allophyllus edulis  2
##  9:       1      Matayba eleagnoides  2
## 10:       1         Cupania vernalis  1
## 11:       1  Capsicodendron dinnisii  1
## 12:       1        Vernonia discolor  1
## 13:       2      Ilex paraguariensis  6
## 14:       2    Nectandra grandiflora  2
## 15:       2         Eugenia uniflora  1
## 16:       2 Campomanesia xanthocarpa  1
## 17:       2   Araucaria angustifolia  5
## 18:       2      Matayba eleagnoides  2
## 19:       2         Mimosa scabrella  1
## 20:       2       Sapium glandulatum  1
## 21:       2 Schinus terebinthifolius  1
## 22:       2   Nectandra megapotamica  1
## 23:       2        Luehea divaricata  1
## 24:       2         Cedrela fissilis  1
## 25:       3 Piptocarpha angustifolia  1
## 26:       3      Ilex paraguariensis  7
## 27:       3 Campomanesia xanthocarpa  1
## 28:       3   Araucaria angustifolia  5
## 29:       3      Matayba eleagnoides  3
## 30:       3   Nectandra megapotamica  1
## 31:       3            Ocotea porosa  1
## 32:       3    Nectandra grandiflora  1
## 33:       3         Mimosa scabrella  1
## 34:       3 Schinus terebinthifolius  1
## 35:       3       Allophyllus edulis  1
## 36:       3              Ilex dumosa  1
## 37:       3     Tabebuia avellanedae  1
## 38:       3       Sapium glandulatum  1
##     Parcela                  Especie ni
# Uma visualização gráfica
ggplot(FOM[, .(ni=.N), by=c("Parcela", "Especie")], 
       aes(x=Especie, y=ni, fill=Especie)) + 
  geom_bar(stat="identity",position="dodge",width = 1,colour="black")+
  geom_text(aes(label=ni,hjust=-.3, vjust=0.5),
            position=position_dodge(width = 0.7))+
  facet_grid(~ Parcela, labeller=labeller(
    Parcela = Parcela<-as_labeller(
      c(`1`="Parcela 1",`2`="Parcela 2",`3`="Parcela 3"))))+
      coord_flip()+
  geom_text(data=ddply(.data=FOM, .(Parcela), summarize, 
                       n=paste("n =", length(Especie))), 
            aes(x=23, y=7, label=n), colour="black", 
            inherit.aes=FALSE, parse=FALSE)+
      theme_bw()+
      theme(axis.line.x=element_line(size=0.5,colour="black"),
        axis.line.y=element_line(size=0.5,colour="black"),
        axis.line=element_line(size=1,colour="black"),
        strip.text.x=element_text(colour=1,size=12,family="serif",face="bold"),
        strip.background = element_rect(colour="black", fill="snow2"),
        panel.grid.major=element_blank(),
        panel.grid.minor=element_blank(),
        panel.border=element_rect(color="black"),
        panel.background=element_blank(),
        axis.text.x=element_text(colour="black",size=12,family="serif",angle=0),
        axis.text.y=element_text(colour=1,size=12,family="serif",face="italic"),
        legend.position="none")+
  scale_x_discrete(name="Espécie")+
  scale_y_continuous(name="Número de indivíduos",
                     limits=c(0,8))

Obtendo os parâmetros fitossociológicos da estrutura horizontal:

1. Densidade absoluta (\(DA_{i}\)): Para obter a \(DA_{i}\) é necessário o conhecimento do número de individuos amostrados da \(i\)-ésima espécie (\(n_{i}\)) e da área total amostra (A):

\[ DA_{i} = \frac{n_{i}}{A} \]

  • \(\color{red}{\textit{Araucaria angustifolia}}\)
DAi <- function(x, A){
  ni <- nrow(subset(FOM, Especie=="Araucaria angustifolia"))
  DAi <- ni/A
  return(DAi)
}

DAi(x = FOM$Especie, A = 0.3)
## [1] 46.66667

2. Densidade relativa (\(DR_{i}\)): Para obter a densidade relativa de cada espécie basta usar a fórmula abaixo. Em que: s = número total de espécies observadas.

\[ DR_{i} = \frac{DA_{i}}{\sum\limits_{i=1}^s \left(DA_{i} \right)} \] - \(\color{red}{\textit{Araucaria angustifolia}}\)

DRi <- function(x, A){
  ni <- nrow(subset(FOM, Especie=="Araucaria angustifolia"))
  DAi <- ni/A
  DTA <- length(x)/A
  DRi <- (DAi/DTA)*100
  return(DRi)
}

DRi(x = FOM$Especie, A = 0.3)
## [1] 20

3. Dominância absoluta (\(DoA_{i}\)) - \(m^2.ha^{-1}\): Para obter a dominância absoluta é necessário o cálculo prévio das áreas transversais (\(g_j\)) da \(j\)-ésima árvore.Em seguida, a área basal da espécie (\(G_i\)) é obtida pela soma das \(g_j\) para cada espécie. Por fim, a \(DoA_{i}\) da \(i\)-ésima espécie é calculada pela razão da \(G_i\) pela área total amostrada (A):

\[ \begin{cases} DoA_{i} = \frac{\sum\limits_{j=1}^{n_i} g_{j}}{A} = \frac{G_{i}}{A} \\\\ g_{j} = \frac{\pi}{40000}.DAP_{j}^2 \end{cases} \] - \(\color{red}{\textit{Araucaria angustifolia}}\)

DoAi <- function(data, A, ...){
  data <- data[Especie=="Araucaria angustifolia"]
  gi <- data[, .(gi=pi*DAP^2/40000)]
  Gi <- sum(gi)
  DoAi <- Gi/A
  return(DoAi)
}

DoAi(data=FOM, A=0.3)
## [1] 11.15996

4. Dominância relativa (\(DoR_{i}\)): A dominância relativa da \(i\)-ésima espécie é calculada pela razão da dominância absoluta de cada espécie (\(DoA_i\)) pela dominância total (soma dos valores de \(DoA_i\) para cada espécie). Alternativamente, pode-se fazer a razão da área basal da \(i\)-ésima espécie (\(G_i\)) pela soma das áreas basais de todas as espécies amostradas (\(G_T\)):

\[ DoR_{i} = \frac{DoA_{i}}{\sum\limits_{i=1}^s \left(DoA_{i} \right)}.100 ~=~ \frac{G_{i}}{G_{T}}.100 \] - \(\color{red}{\textit{Araucaria angustifolia}}\)

DoRi <- function(data, A, ...){
  Gt <- data[, .(gi=pi*DAP^2/40000)]
  data <- data[Especie=="Araucaria angustifolia"]
  gi <- data[, .(gi=pi*DAP^2/40000)]
  Gi <- sum(gi)
  DoAi <- Gi/A
  DoRi <- (Gi/sum(Gt))*100
  return(DoRi)
}

DoRi(data=FOM, A=0.3)
## [1] 53.50602

5. Frequência absoluta (\(FA_{i}\)): A frequência absoluta de cada espécie é calculada pela razão do número de unidades de amostras (\(U_i\)) onde foram encontradas a \(i\)-ésima espécie e o número total de unidades de amostras (\(U_T\)). Pode-se multiplicar por 100 para obter o parâmetro relativizado:

\[ FA_{i} = \frac{U_{i}}{U_{T}}.100 \] - \(\color{red}{\textit{Araucaria angustifolia}}\)

FAi <- function(data, ...){
  Ut <- length(unique(data$Parcela))
  Ui <- unique(data, by=c("Especie", "Parcela"))[, .(Ui=.N), by="Especie"]
  Ui <- Ui[Especie=="Araucaria angustifolia", Ui]
  FAi <- (Ui/Ut)*100
  return(FAi)
}

FAi(data=FOM)
## [1] 100

6. Frequência relativa (\(FR_{i}\)): A frequência relativa da \(i\)-ésima espécie é calculada pela razão da frequência absoluta de cada espécie (\(FA_i\)) pela frequência total (soma dos valores de \(FA_i\) para cada espécie):

\[ FR_{i} = \frac{FA_{i}}{\sum\limits_{i=1}^s \left(FA_{i} \right)}.100 \] - \(\color{red}{\textit{Araucaria angustifolia}}\)

FRi <- function(data, ...){
  Ut <- length(unique(FOM$Parcela))
  Ui <- unique(FOM, by=c("Especie", "Parcela"))[, .(Ui=.N), by="Especie"]
  FAi <- Ui[, .(FAi=(Ui/length(unique(FOM$Parcela)))*100)]
  Ui_AA <- Ui[Especie=="Araucaria angustifolia", Ui]
  FAi_AA <- (Ui_AA/Ut)*100
  FRi <- (FAi_AA /sum(FAi))*100
  return(FRi)
}

FRi(data=FOM)
## [1] 7.894737

7. Valor de cobertura (\(VC_{i}\)): O valor de cobertura integra os parâmetros de densidade e dominância relativa, isto é, o \(VC_i\) é soma de \(DR_i\) e \(DoR_i\) de cada espécie:

\[ VC_{i} = DR_{i} + DoR_{i} \] - \(\color{red}{\textit{Araucaria angustifolia}}\)

VCi <- DRi(x = FOM$Especie, A = 0.3) + DoRi(data=FOM, A=0.3)
VCi
## [1] 73.50602

8. Porcentagem de cobertura (\(PC_{i}\)): Por extensão, pode-se obter a porcentagem de cobertura da \(i\)-ésima espécie fazendo-se a média de \(DR_i\) e \(DoR_i\):

\[ PC_{i} = \frac{DR_{i} + DoR_{i}}{2} \] \(\color{red}{\textit{Araucaria angustifolia}}\)

PCi <- (DRi(x = FOM$Especie, A = 0.3) + DoRi(data=FOM, A=0.3))/2
PCi
## [1] 36.75301

9. Valor de importância (\(VI_{i}\)): O valor de importância integra os parâmetros de densidade, dominância e frequência relativa, isto é, o \(VI_i\) é soma de \(DR_i\), \(DoR_i\) e \(FR_i\) de cada espécie:

\[ VI_{i} = DR_{i} + DoR_{i} + FR_{i} \] - \(\color{red}{\textit{Araucaria angustifolia}}\)

VIi <- DRi(x = FOM$Especie, A = 0.3) + DoRi(data=FOM, A=0.3) + FRi(data=FOM)
VIi
## [1] 81.40076

10. Porcentagem de importância (\(PI_{i}\)): Por extensão, pode-se obter a porcentagem de importância da \(i\)-ésima espécie fazendo-se a média de \(DR_i\), \(DoR_i\) e \(FR_i\):

\[ PI_{i} = \frac{DR_{i} + DoR_{i} + FR_{i}}{3} \] - \(\color{red}{\textit{Araucaria angustifolia}}\)

PIi <- (DRi(x = FOM$Especie, A = 0.3) + DoRi(data=FOM, A=0.3) + FRi(data=FOM))/3
PIi
## [1] 27.13359

Inicialmente, para melhor compreensão dos cálculos os parâmetros da estrutura horizontal foram obtidos apenas para a espécie \(\color{red}{\textit{Araucaria angustifolia}}\). Porém, é possível obter todas as estimativas criando-se apenas uma única função no ambiente R. A seguir é apresentada uma função genérica para obter os parâmetros fitossociológicos da estrutura horizontal. A função EH recebe quatro parâmetros: species = vetor contendo as espécies inventariadas; sample = vetor indicando as parcelas de ocorrência das espécies; d = vetor com diâmetro das árvores; e A = escalar indicando a área total amostrada:

# Uma função genérica
EH <- function(species, sample, d, A,...){
  DT <- data.table(species=species,sample=sample,d=d)
  DT <- DT[,`:=`(gi=pi*d^2/40000)]
  Ui <- unique(DT, by=c("species", "sample"))[, .(Ui=.N), by="species"][order(species)]
  ni <- DT[, .(ni=.N, Gi = sum(gi)), by="species"]
  ni <- ni[Ui,on="species"]
  EH <- ni[,DAi := ni/A,
           ][,DRi := (DAi/sum(DAi))*100,
             ][,DoAi := Gi/A,
               ][,DoRi := (DoAi/sum(DoAi))*100,
                 ][,VC := DRi + DoRi,
                   ][,PC := VC/2,
                     ][,FAi := (Ui/length(unique(DT$sample)))*100,
                       ][,FRi := (FAi/sum(FAi))*100,
                         ][,VIi := DRi + DoRi + FRi,
                           ][,PIi := VIi/3][order(-VIi)]
  return(EH)
}
EH <- EH(species=FOM$Especie, sample=FOM$Parcela, d=FOM$DAP, A=0.3)

kable(EH, format = "html", booktabs = TRUE) %>%
  kable_styling(font_size = 14) %>%
  kableExtra::landscape()
species ni Gi Ui DAi DRi DoAi DoRi VC PC FAi FRi VIi PIi
Araucaria angustifolia 14 3.3479867 3 46.666667 20.000000 11.1599555 53.5060230 73.506023 36.7530115 100.00000 7.894737 81.400760 27.133587
Ilex paraguariensis 17 0.5565488 3 56.666667 24.285714 1.8551628 8.8945144 33.180229 16.5901143 100.00000 7.894737 41.074965 13.691655
Matayba eleagnoides 7 0.3805560 3 23.333333 10.000000 1.2685201 6.0818762 16.081876 8.0409381 100.00000 7.894737 23.976613 7.992204
Ocotea porosa 2 0.7369901 2 6.666667 2.857143 2.4566338 11.7782464 14.635389 7.3176946 66.66667 5.263158 19.898547 6.632849
Campomanesia xanthocarpa 4 0.1482714 3 13.333333 5.714286 0.4942380 2.3696070 8.083893 4.0419463 100.00000 7.894737 15.978630 5.326210
Nectandra grandiflora 3 0.0675364 2 10.000000 4.285714 0.2251213 1.0793363 5.365051 2.6825253 66.66667 5.263158 10.628208 3.542736
Allophyllus edulis 3 0.0515677 2 10.000000 4.285714 0.1718922 0.8241314 5.109846 2.5549229 66.66667 5.263158 10.373004 3.457668
Mimosa scabrella 2 0.1188307 2 6.666667 2.857143 0.3961025 1.8990997 4.756242 2.3781213 66.66667 5.263158 10.019400 3.339800
Nectandra megapotamica 2 0.1030953 2 6.666667 2.857143 0.3436510 1.6476227 4.504766 2.2523828 66.66667 5.263158 9.767924 3.255975
Schinus terebinthifolius 2 0.0780097 2 6.666667 2.857143 0.2600322 1.2467156 4.103859 2.0519293 66.66667 5.263158 9.367016 3.122339
Sapium glandulatum 2 0.0568133 2 6.666667 2.857143 0.1893778 0.9079655 3.765108 1.8825542 66.66667 5.263158 9.028266 3.009422
Cedrela fissilis 1 0.1170212 1 3.333333 1.428571 0.3900706 1.8701802 3.298752 1.6493758 33.33333 2.631579 5.930331 1.976777
Ilex dumosa 1 0.1000982 1 3.333333 1.428571 0.3336607 1.5997248 3.028296 1.5141481 33.33333 2.631579 5.659875 1.886625
Luehea divaricata 1 0.0934820 1 3.333333 1.428571 0.3116067 1.4939877 2.922559 1.4612796 33.33333 2.631579 5.554138 1.851379
Tabebuia avellanedae 1 0.0688134 1 3.333333 1.428571 0.2293782 1.0997457 2.528317 1.2641585 33.33333 2.631579 5.159896 1.719965
Piptocarpha angustifolia 1 0.0611362 1 3.333333 1.428571 0.2037873 0.9770510 2.405622 1.2028112 33.33333 2.631579 5.037201 1.679067
Drymis brasiliensis 1 0.0444881 1 3.333333 1.428571 0.1482936 0.7109888 2.139560 1.0697801 33.33333 2.631579 4.771139 1.590380
Vernonia discolor 1 0.0444881 1 3.333333 1.428571 0.1482936 0.7109888 2.139560 1.0697801 33.33333 2.631579 4.771139 1.590380
Capsicodendron dinnisii 1 0.0376685 1 3.333333 1.428571 0.1255616 0.6020008 2.030572 1.0152861 33.33333 2.631579 4.662151 1.554050
Ocotea pulchella 1 0.0141026 1 3.333333 1.428571 0.0470087 0.2253816 1.653953 0.8269765 33.33333 2.631579 4.285532 1.428511
Eugenia uniflora 1 0.0136848 1 3.333333 1.428571 0.0456159 0.2187040 1.647275 0.8236377 33.33333 2.631579 4.278854 1.426285
Maytenus ilicifolia 1 0.0081713 1 3.333333 1.428571 0.0272376 0.1305898 1.559161 0.7795806 33.33333 2.631579 4.190740 1.396913
Cupania vernalis 1 0.0078540 1 3.333333 1.428571 0.0261799 0.1255188 1.554090 0.7770451 33.33333 2.631579 4.185669 1.395223

REFERENCIAL TEÓRICO

1. Manuais técnicos

- is based on the former “Notes on R”, gives an introduction to the language and how to use R for doing statistical analysis and graphics.

2. Legislação

BRASIL. Resolução nº 406, de 2 de fevereiro de 2009. Estabelece parâmetros técnicos a serem adotados na elaboração, apresentação, avaliação técnica e execução de Plano de Manejo Florestal Sustentável - PMFS com fins madeireiros, para florestas nativas e suas formas de sucessão no bioma Amazônia. Diário Oficial [da República Federativa do Brasil], Brasília, nº 26, p. 100, 6 de fevereiro de 2009. Seção 1.

DOWLE, M.; SRINIVASAN, A. data.table: Extension of ‘data.frame‘. Traducao. [s.l.] R package version 1.10.4-3, 2017.

DRAGULESCU, A. A. xlsx: Read, write, format Excel 2007 and Excel 97/2000/XP/2003 files. Traducao. [s.l.] R package version 0.5.7, 2014.

FAN, F. Y. FinCal: Time Value of Money, Time Series Analysis and Computational Finance. Traducao. [s.l.] R package version 0.6.3., 2016.

FARAWAY, J. faraway: Functions and Datasets for Books by Julian Faraway. Traducao. [s.l.] R package version 1.0.7, 2016.

FOX, J.; WEISBERG, S. An R Companion to Applied Regression. Traducao. Second ed. Thousand Oaks CA: Sage, 2011.

MAKIYAMA, K. magicfor: Magic Functions to Obtain Results from for Loops. Traducao. [s.l.] R package version 0.1.0, 2016.

MUELLER-DOMBOIS, D.; ELLENBERG, H. Aims and methods of vegetation ecology. 1974.

NAVARRO, D. Learning statistics with R: A tutorial for psychology students and other beginners. (Version 0.5). Traducao. Adelaide, Australia: University of Adelaide, 2015.

PÉLLICO NETO, S.; BRENA, D. Inventário florestal. Traducao. [s.l.] Curitiba.[Links], 1997.

PONCET, P. modeest: Mode Estimation. Traducao. [s.l.] R package version 2.1, 2012.

QUEIROZ, W. T. DE. Técnicas de amostragem em inventário florestal nos trópicos. Traducao. [s.l.] Ministerio da Educação e do Desporto, Faculdade de Ciências Agrárias de Pará, Serviço de Documentação e Informação, 1998.

R CORE TEAM. R: A Language and Environment for Statistical Computing. Traducao. Vienna, Austria: R Foundation for Statistical Computing, 2017.

SANQUETTA, C. et al. Inventários florestais: planejamento e execução. Traducao. 3. ed. Curitiba PR: Curitiba: Multi-Graphic, 2014.

SANQUETTA, C. et al. Inventários florestais: planejamento e execução. Traducao. 2. ed. [s.l: s.n.].

SOUZA, A. L.; SOARES, C. P. B. Florestas Nativas: estrutura, dinâmica e manejo. Traducao. Viçosa MG: UFV, 2013.

ZEILEIS, A.; HOTHORN, T. Diagnostic Checking in Regression Relationships. R News, v. 2, n. 3, p. 7–10, 2002.